Skip to main content
ClickHouse Connect 内置了一个基于核心驱动构建的 clickhousedb SQLAlchemy 方言。它支持 SQLAlchemy 1.4.40 及更高版本 (包括 SQLAlchemy 2.x) ,重点关注 Core 查询、ClickHouse DDL、反射以及简单的 ORM 插入。 通过包扩展安装 SQLAlchemy 依赖项:

使用 SQLAlchemy 进行连接

使用 clickhousedb://clickhousedb+connect:// 这两种 URL 格式之一创建引擎:
URL 查询参数可以包含 ClickHouse 设置、ClickHouse Connect 客户端选项 (例如 compressionquery_limit 和超时设置) ,或 HTTP/TLS 选项 (例如 ca_cert) 。如有需要,可为 ClickHouse 设置添加 ch_ 前缀,以强制将其识别为服务器设置,例如 ch_http_max_field_name_size=99999 可用的客户端选项请参见连接参数和设置

每个查询的设置

通过 SQLAlchemy 的执行选项传递 ClickHouse 设置。可以在引擎、连接或语句上设置这些参数。对于相同的键,语句上的值优先于连接或引擎上的值。

按查询设置读取格式

通过 SQLAlchemy 的执行选项 query_formats,可为引擎、连接或语句设置 ClickHouse 读取格式。语句级格式会优先应用,并覆盖匹配的连接级或引擎级键及通配符。

服务器端参数

SQLAlchemy 通常会在客户端渲染参数。创建引擎时,可选择启用 ClickHouse 服务器端参数:
在此模式下,每个绑定值都必须具有与 ClickHouse 兼容的 SQLAlchemy 类型。受支持的 IN 列表会变为带类型的 ClickHouse Array 参数。如果编译器无法推导出兼容的类型,或无法安全地处理绑定值,就会引发 CompileError

Core 查询

该方言支持 SQLAlchemy Core SELECT 查询,可使用 JOIN、过滤器、排序、LIMIT 和 OFFSET 以及 DISTINCT
支持轻量级 DELETE,并且需要显式 WHERE 子句:

JSON 子列

对于声明为或映射为 ClickHouse JSON 的列,请使用方括号逐段选择由存储支持的子列路径:
payload["severity"] 会被编译为 ClickHouse 的点分标识符语法。每个部分都会分别加引号,例如 `events`.`payload`.`severity`。它读取 ClickHouse 存储的 JSON 子列,不会调用 getSubcolumn。对路径中的每个分段依次使用 [].subcolumn()。每个分段都必须是非空字符串。 .subcolumn() 传入 type_ 会将点分路径包装为 SQL CAST,并将该类型赋予 SQLAlchemy 表达式。未传入 type_ 时,.subcolumn("segment") 的行为与 ["segment"] 相同。 未指定类型的路径具有 ClickHouse 的 Dynamic 类型。ClickHouse 不允许在 ORDER BYGROUP BY 中直接使用 Dynamic 值。当在这些位置使用子列时,请传入 type_ 对于静态类型代码,请从 clickhouse_connect.cc_sqlalchemy 导入 json_subcolumn。该辅助函数同样每次只接受一个分段,并保留 type_ 指定的 Python 结果类型:
在此示例中,类型检查器会将 request_id 识别为 ColumnElement[int] 每个片段都会分别加引号,包括包含空格或反引号的名称。对于 ClickHouse JSON 路径处理,反引号不会使点号成为字面量。启用 json_type_escape_dots_in_keys 后,键名中的字面点号应使用 ClickHouse 的 %2E 编码。对于名为 a.b 的键,应通过 payload["a%2Eb"] 而非 payload["a.b"] 访问。

ClickHouse 查询扩展

clickhouse_connect.cc_sqlalchemy 导入 select,即可向静态类型检查器公开带类型的 ClickHouse 方法。标准的 sqlalchemy.select 在运行时也提供这些方法。
ClickHouse Select 方法如下: 例如,ClickHouse GLOBAL ANY LEFT JOIN 可以链式调用,无需嵌套自定义 FromClause
对 ClickHouse 高阶函数,请使用显式的 Lambda 构造:
标准的 SQLAlchemy values() 构造会被编译为 ClickHouse 的 VALUES 表函数语法,包括在公共表表达式中使用时。CTE 形式需要 SQLAlchemy 2.0.42 或更高版本,其中新增了 Values.cte()

Materialized CTE

默认情况下,ClickHouse 会内联公共表表达式,因此被多次引用的 CTE 的主体会针对每次引用执行一次。向 .cte() 传入 materialized=True,即可生成 WITH <name> AS MATERIALIZED (...),使主体只计算一次:
仅当指定该关键字、enable_materialized_cte=1 且启用 analyzer 时,服务器 才会 materialize CTE。如每个查询的设置所示,可在语句、连接 或 引擎 上设置 enable_materialized_cte。在所有支持此功能的服务器 上,analyzer 默认启用,因此显式设置 enable_analyzer=1 是一种防御性措施。enable_materialized_cte 是一项 Experimental ClickHouse 设置。使用 enable_materialized_cte=0enable_analyzer=0 时,查询仍会成功执行并返回相同的行。ClickHouse 会静默忽略 MATERIALIZED 并重新内联 CTE,因此漏设该选项只会影响性能,不会报错。Materialized CTEs 需要 ClickHouse 26.3 或更高版本。旧版服务器 会将该关键字视为语法错误而拒绝。 对于使用标准 sqlalchemy.select 构建的语句,请改用模块级的 cte()。它将语句 作为第一个 argument,其他行为与 Select.cte() 一致:
该关键字仅在 ClickHouse 方言下生效,因此与其他后端共享的语句在该方言下可原样编译。 ClickHouse 不支持递归 materialized CTE。若同时设置 recursive=Truematerialized=True,SQLAlchemy helpers 将引发 ValueError

DDL 与反射

ClickHouse Connect 提供 ClickHouse 数据类型、表引擎、字典结构、数据库 DDL 和表反射功能。
反射出的列会为 DEFAULT 表达式带上 server_default,并在存在时包含方言特有的属性,例如 clickhouse_codecclickhouse_ttlclickhouse_materializedclickhouse_alias MergeTree 键参数 (如 order_bypartition_byprimary_keysample_byttl) 既接受 SQLAlchemy 列和 SQL 表达式,也接受普通字符串。

插入和基本 ORM 用法

支持 Core 插入以及简单的 ORM 模型。对于批量数据路径,优先使用 Core 插入。

Alembic 迁移

ClickHouse Connect 提供了适用于 ClickHouse schema 迁移的 Alembic 集成。使用以下命令安装:
在 Alembic 的 env.py 中导入 clickhouse_connect.cc_sqlalchemy.alembic,以注册方言集成。自动生成支持常见的表结构变更,包括创建和删除表、添加/修改/删除列、默认值以及注释。表和列的重命名请使用手动操作。在应用每个生成的迁移之前,都应先进行审查。 ClickHouse 特有的 op.* 辅助方法涵盖:
  • 数据跳过索引,包括添加、物化和删除操作。
  • 投影,包括添加、物化和删除操作。
  • MergeTree 表设置的修改与重置。
  • materialized view 的创建与删除。
  • 字典的创建、删除和重新加载。
ClickHouse 数据跳过索引不是 SQLAlchemy 索引。IndexColumn(index=True)op.create_indexop.drop_index 都会被拒绝,以避免生成不完整或不正确的 DDL。请使用 op.add_clickhouse_indexop.drop_clickhouse_index 请参阅完整的 Alembic 示例。从 clickhouse-sqlalchemy 迁移的用户还应阅读迁移指南

范围和限制

  • ClickHouse 不通过此 HTTP 方言提供传统事务。engine.begin()Session.commit() 用于组织 Python 端的工作,但 commit 和 rollback 在服务器端都是空操作。
  • 该方言未实现 UPDATE、两阶段事务、序列、RETURNING 以及高级隔离级别。需要执行服务器端变更时,请显式使用 ClickHouse SQL。
  • Column(..., primary_key=True) 提供的是 SQLAlchemy 的对象标识。它不会创建服务器端的唯一性约束。请通过表引擎定义排序和可选的主键表达式。
  • 传统的外键、唯一约束以及标准索引元数据不可用,因为 ClickHouse 不会强制执行这些约束。
  • ORM 关系管理、工作单元更新、级联,以及立即或延迟的关系加载,不属于受支持的 ORM 范围。
最后修改于 2026年8月14日