跳转至

ClickHouse 连接器

ClickHouse 通过它的 HTTP 接口接入。一条语句一个请求;结果默认是 JSONCompact,构建里带了 Arrow feature 时则是真正的 Arrow 流。

每个请求都会带三项设置,好让结果能和别的引擎比对:session_timezone=UTC、64 位整数不加引号、以及把库名作为查询参数带上。这里没有连接池——一个保活的 HTTP 客户端,连接超时 10 秒、请求超时 60 秒。由 exec-http 控制,Arrow 路径还需要 exec-http-arrow

连接配置

datasources:
  ch:
    type: clickhouse
    uri: http://ch.internal:8123
    username: default
    password: ${CLICKHOUSE_PASSWORD}
    database: analytics

也可以用 host:/port: 代替 uri:,端点会被拼成 http://<host>:<port>

参数

类型 必填 默认 说明
type string clickhouse
uri string 是* *或者给 host:。带 scheme 的完整端点。
host string 是* *或者给 uri:。用来拼成 http://<host>:<port>——固定是 http,所以 HTTPS 端点必须显式写 uri:
port int 8123 只有从 host: 拼端点时才用到。
username string 作为 X-ClickHouse-User 头发送。
password string 作为 X-ClickHouse-Key 头发送。尽量用 ${VAR}
database string 每个请求都会带上的查询参数。
default bool false 连接配置

本连接器解析但不使用的键: schemacatalogsslmodesslrootcert(TLS 取决于 URL 的 scheme,而不是这两个键)、arrow_flight_portaccountrolewarehousecompat_mode

HTTPS 需要带 TLS 的构建

只启用 exec-http 时,链接进去的 HTTP 客户端不带 TLS,所以在只有 exec-http 的构建里 https:// 端点会失败。官方二进制和 Python wheel 都带 exec-all,不受影响;自己编译的要加 --features exec-all(或者任何同时包含 exec-snowflake / exec-databricks 的组合,它们会把 TLS 栈带进来)。

Arrow 原生结果

带上 exec-http-arrow 之后,同一个端点会被请求为 ArrowStream,批次以 lz4 分帧的真流解码——配置一个字都不用改。见 Arrow

有一处转换是自动做的:ClickHouse 的 Arrow writer 把 Date 导出成裸 UInt16(epoch 天数)、把 DateTime 导出成裸 UInt32(epoch 秒),所以适配器会先跑一次 DESCRIBE (query)——只做类型推断、不执行——再把这些列重新定型成 Date32/Timestamp。Date32DateTime64 本来就导得对。

已知限制

  • 没有 cume_dist ClickHouse 的窗口函数里有 percent_rank,但没有 cume_dist,所以用到它的指标在这个方言下会在编译期被拒,而不是拿别的函数顶替。
  • UNION 会被发成 UNION DISTINCT,因为 union_default_mode 没设时 ClickHouse 会拒绝裸的 UNION——编译器已经处理,不用配置。
  • 左连接和全连接会附带 join_use_nulls = 1,因为 ClickHouse 默认把 JOIN 未命中填成 0 而不是 NULL——同样已经替你处理好,这也是 ClickHouse 的结果能和 DuckDB 对上的原因。

本地验证连接

$ dosi query --model model.yaml \
    --metrics revenue --group-by orders.status --execute --connection ch

排错

报错 原因与处理
connection "x" (clickhouse) is missing required field "uri" uri:host:
HTTP 401: <body> / HTTP 403: <body> 凭据或权限——响应体是 ClickHouse 自己的话。
https:// URL 上的 HTTP 404: <body> 多半是上面那条 TLS 注意事项:只有 exec-http 的构建讲不了 HTTPS。
cannot reach server: <e> 主机、端口或网络;确认配置里写的是 HTTP 接口(8123),而不是原生协议端口(9000)。
bad JSONCompact response: <e> 端点返回的不是 ClickHouse 结果——通常是走了代理或者端口错了。
bad DESCRIBE response: <e> / bad ArrowStream response: <e> 仅 Arrow 路径:服务端的响应解不出来。

参考链接