You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在Clojure中捕获CQL删除列语句的特定异常问题排查

解决Cassandra DROP COLUMN时无法捕获InvalidQueryException的问题

问题核心是Alia库会将Datastax驱动抛出的原始异常包装成自身的异常类型,所以你直接捕获com.datastax.driver.core.exceptions.InvalidQueryException会失效——实际抛出的是Alia封装后的异常,原始异常被作为cause嵌套在里面。

解决步骤

  1. 先确认异常的实际类型:
    在通用Exception分支里,打印异常的完整信息和嵌套的根异常:

    (catch Exception e
      (prn "当前异常类:" (class e))
      (prn "根异常:" (.getCause e))
      (prn "异常信息:" (.getMessage e)))
    

    你会发现实际抛出的是qbits.alia.error.ExecutionException这类Alia自定义异常,原始的InvalidQueryException是它的根异常。

  2. 修改异常捕获逻辑,以下是两种可行实现:

方案一:直接捕获Alia执行异常并检查根异常

(ns my-namespace
  (:require [qbits.alia :as alia]
            [qbits.hayt :as hayt])
  (:import [com.datastax.driver.core.exceptions InvalidQueryException]
           [qbits.alia.error ExecutionException]))

(defn drop-column-safe
  [session]
  (try
    (alia/execute session
                  (hayt/alter-table :my_table
                                    (hayt/drop-column :my_col)))
    (catch ExecutionException ee
      (if (instance? InvalidQueryException (.getCause ee))
        (prn "指定列不存在,无需删除")
        (prn "执行出错:" (.getMessage ee))))
    (catch Exception e
      (prn "其他未知错误:" (.getMessage e)))))

方案二:在通用分支中递归判断根异常类型

(ns my-namespace
  (:require [qbits.alia :as alia]
            [qbits.hayt :as hayt])
  (:import [com.datastax.driver.core.exceptions InvalidQueryException]))

(defn drop-column-safe
  [session]
  (try
    (alia/execute session
                  (hayt/alter-table :my_table
                                    (hayt/drop-column :my_col)))
    (catch Exception e
      (let [root-cause (loop [cause e]
                         (if (.getCause cause)
                           (recur (.getCause cause))
                           cause))]
        (if (instance? InvalidQueryException root-cause)
          (prn "指定列不存在,无需删除")
          (prn "错误信息:" (.getMessage e)))))))

额外优化方案:主动检查列是否存在

你也可以通过查询Cassandra系统表system_schema.columns预先判断列是否存在,再执行DROP操作,这种方式更主动:

(defn column-exists?
  [session keyspace table column]
  (let [result (alia/execute session
                             (hayt/select :system_schema.columns
                                          (hayt/where :keyspace_name keyspace
                                                      :table_name table
                                                      :column_name column)))]
    (not-empty result)))

(defn drop-column-if-exists
  [session]
  (when (column-exists? session "你的键空间名称" "my_table" "my_col")
    (alia/execute session
                  (hayt/alter-table :my_table
                                    (hayt/drop-column :my_col)))))

内容的提问来源于stack exchange,提问作者BrianN

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.10 21:30:53