对于客户端工厂以及具有大量可选参数的方法,建议使用关键字参数传参。此处未文档说明的方法不属于 API 的一部分,后续可能会被移除或更改。
客户端初始化
使用clickhouse_connect.get_client 创建同步 Client;或者安装 async 扩展,并通过 await 调用 clickhouse_connect.get_async_client 来创建原生 AsyncClient。
连接参数
同步和异步 HTTP 工厂都会对以下客户端选项进行字符串值转换,这些值可来自 DSN 查询参数或
generic_args:connect_timeout、send_receive_timeout、query_limit 和 query_retries 会转换为上文所示的数值类型;autogenerate_query_id、autogenerate_session_id 和 form_encode_query_params 会转换为布尔值。如果这些选项的字符串值无效,则会引发 ProgrammingError。
异步工厂还接受 connector_limit=100、connector_limit_per_host=20 和 keepalive_timeout=30.0,用于配置其 aiohttp 连接池。这些参数可以作为关键字参数直接传入,也可以通过 DSN 查询参数或 generic_args 传入 (generic_args 在内部用于 SQLAlchemy 的 connect_args) 。这些连接器选项的字符串值会转换为文档所述的数值类型。上述选项的字符串值无效时,会引发 ProgrammingError。优先次序依次为:显式传入的非 None 关键字参数、generic_args、DSN。异步工厂不接受 pool_mgr。同步 chDB 后端接受 path 和 chdb_options;参见 嵌入式 chDB 后端。
HTTPS/TLS 参数
Settings 参数
最后,get_client 的 settings 参数用于在每次客户端请求时,向服务器传递额外的 ClickHouse 设置。请注意,在大多数情况下,具有 readonly=1 权限的用户无法修改随查询一起发送的设置,因此 ClickHouse Connect 会在最终请求中丢弃此类设置,并记录一条警告。以下设置仅适用于 ClickHouse Connect 使用的 HTTP 查询/会话,不属于通用 ClickHouse 设置文档中的内容。
有关可随每个查询一起发送的其他 ClickHouse 设置,请参阅 ClickHouse 文档。
客户端创建示例
- 在不传入任何参数的情况下,ClickHouse Connect 客户端会使用 default 用户且不设置密码,连接到
localhost的默认 HTTP 端口:
- 连接到安全 (HTTPS) 的外部 ClickHouse 服务器
- 使用会话 ID、其他自定义连接参数以及 ClickHouse 设置进行连接。
嵌入式 chDB 后端
安装clickhouse-connect[chdb] 以使用 Experimental 的进程内 chDB 后端。它提供同步客户端的查询、插入、流式和 Arrow 方法:
path="/data/my_chdb" 或使用 dsn="chdb:///data/my_chdb" 可启用持久化存储。该后端每个进程只允许使用一个 engine 路径,并且不支持 get_async_client 或外部数据。
客户端生命周期和最佳实践
创建 ClickHouse Connect 客户端的开销较大,因为这需要建立连接、获取服务器元数据并初始化设置。请遵循以下最佳实践以获得最佳性能:核心原则
- 复用客户端:在应用启动时创建一次客户端,并在整个应用生命周期内重复使用
- 避免频繁创建:不要为每个查询或请求都新建客户端
- 正确清理:应用关闭时务必关闭客户端,以释放连接池资源
- 尽可能共享:单个客户端可通过其连接池处理大量并发查询 (参见下方的线程说明)
基本原则
复用同一个客户端:多线程应用
要在线程间安全地共享客户端:正确清理
务必在关闭时关闭客户端。请注意,只有当客户端拥有自己的连接池管理器时 (例如,使用自定义 TLS/代理选项创建时) ,client.close() 才会释放客户端并关闭池化的 HTTP 连接。对于默认的共享连接池,请使用 client.close_connections() 主动清理套接字;否则,连接会在空闲超时后以及进程退出时自动回收。
何时使用多个客户端
多个客户端适用于以下情况:- 不同的服务器:每个 ClickHouse 服务器或集群使用一个客户端
- 不同的凭据:针对不同用户或不同访问级别分别使用独立客户端
- 不同的数据库:当你需要使用多个数据库时
- 隔离的会话:当你需要为临时表或会话级设置使用独立会话时
- 按线程隔离:当线程需要独立会话时 (如上所示)
常用方法参数
多个客户端方法会使用通用的parameters 和/或 settings 参数。下面将介绍这些关键字参数。
Parameters 参数
ClickHouse Connect 客户端的query* 和 command 方法都接受一个可选的 parameters 关键字参数,用于将 Python 表达式绑定到 ClickHouse 值表达式。提供两种绑定方式。
服务器端绑定
ClickHouse 支持对查询值使用服务器端绑定。绑定的值会作为 HTTP 参数与查询分开发送。ClickHouse Connect 在检测到形如{<name>:<datatype>} 的表达式时,会使用此模式。请以 Python 字典形式传入这些值。
参数名称必须是 ClickHouse ASCII BareWord 名称。只要服务器接受,驱动程序允许在名称开头、中间或末尾使用 $,例如 {$tenant_id:String}。以 $ 开头和结尾,且值为 bytes、bytearray 或 memoryview 等缓冲区类型的字典键,保留给 ClickHouse Connect 的原始二进制参数约定。如果此类键用于非二进制服务器端参数,请仅使用一个 {name:Type} 占位符。重复的 $tag$ 名称可能会被 ClickHouse 解析为 Heredoc 标记。
对于可空值,请使用 Python None。Array 和 Tuple 参数中支持嵌套的 None 值;当 dict_parameter_format 设置为 "map" 时,Map 字面量中也支持嵌套的 None 值。
- 使用 Python 字典、日期时间值和字符串值的服务器端绑定
SELECT 查询和 INSERT ... VALUES 语句。如需批量插入大量普通数据,建议使用 Client.insert。
客户端绑定
ClickHouse Connect 也支持客户端参数绑定,这样在生成模板化 SQL 查询时会更灵活。对于客户端绑定,parameters 参数应为字典或序列。客户端绑定使用 Python 的”printf” 风格字符串格式化进行参数替换。
请注意,与服务器端绑定不同,客户端绑定不适用于数据库标识符,例如 database、表或列名,因为 Python 风格的格式化无法区分不同类型的字符串,而这些字符串需要采用不同的格式化方式 (数据库标识符使用反引号或双引号,数据值使用单引号) 。
- 使用 Python Dictionary、日期时间 值和字符串转义的示例
- Python Sequence (Tuple) 、Float64 和 IPv4Address 示例
Datetime 绑定会将不带时区信息的值视为墙钟时间。客户端会原样格式化不带时区信息的 为保持向后兼容,如果字典参数名以
datetime。ClickHouse 会根据服务器端占位符中声明的时区 (例如 {dt:DateTime('Europe/Berlin')}) 解释它,随后使用已设置的 session_timezone,最后使用服务器时区。带时区信息的 datetime 会转换为占位符中声明的时区 (如有) ,否则转换为连接时报告的服务器时区。如果 session_timezone 设置与报告的服务器时区不同,请在占位符中声明时区,以确保带时区信息的值保持预期的时间点。如需临时兼容较旧的主机本地转换方式,请在绑定参数前设置 common.set_setting("naive_datetime_binding", "legacy")。为保留时间点,请在将 datetime 值作为参数传递前附加预期的 tzinfo。默认情况下,通过 client.insert 向 DateTime 或 DateTime64 列插入时,会在进程本地时区中解释不带时区信息的 datetime 值。将全局 naive_datetime_insert 设置设为 "server",可将其解释为列时区中的墙钟时间;如果列没有时区,则使用服务器时区。请参阅不带时区信息的 datetime 对象。向 Date 和 Date32 列执行原生插入时,会直接使用 Python datetime 值自身的日历日期,不进行时区转换。如果插入和查询参数需要使用相同的日历日期,请显式传入 value.date()。请参阅Date 和 Date32 值。对于服务器端的 {value:DateTime64(precision)} 占位符,已声明的类型会自动保留子秒级精度,在 Array 和 Tuple 提示中也是如此。客户端 %s 绑定没有声明类型。如果必须以子秒级精度进行格式化,请将 datetime 封装在 DT64Param 中:_64 结尾,即使查询中不存在这个带该后缀的确切名称,也会请求按 DateTime64 格式进行格式化。datetime.time 或 datetime.timedelta 参数会格式化为 [-]HH:MM:SS[.ffffff] 字面量,适用于 ClickHouse Time 和 Time64 列;无论使用哪种绑定方式,也包括 Array 和 Tuple 值中的参数。客户端会添加引号,因此不要在查询中为占位符加引号。timedelta 可以为负数,也可以超过 24 小时。pandas Timedelta 会保留纳秒,并为 Time64(9) 格式化为九位小数部分。带时区信息的 time 中的时区信息会被忽略,因为 ClickHouse Time 没有时区。Settings 参数
所有关键的 ClickHouse Connect 客户端 “insert” 和 “select” 方法都接受一个可选的settings 关键字参数,用于为包含的 SQL 语句传递 ClickHouse 服务器的用户设置。settings 参数应为一个字典。每一项都应包含一个 ClickHouse 设置名称及其对应的值。请注意,这些值在作为查询参数发送到服务器时会被转换为字符串。
与客户端级别的设置一样,ClickHouse Connect 会丢弃任何被服务器标记为 readonly=1 的设置,并记录相应的日志消息。仅适用于通过 ClickHouse HTTP 接口 发起查询的设置始终有效。这些设置在 get_client API 下有说明。
使用 ClickHouse 设置的示例:
Client command 方法
对于不返回表格数据集的语句,或者返回单个基本类型值或单行的查询,请使用 Client.command。根据响应内容,它会返回字符串、整数、字符串序列或 QuerySummary。如果读取操作产生空结果集,则返回空字符串。
命令示例
DDL 语句
返回单个值的简单查询
带参数的命令
带设置的命令
Client query 方法
Client.query 以 ClickHouse Native 格式检索表格数据集,并返回一个 QueryResult。访问结果属性时,会将完整结果 materialized。对于不应保存在内存中的结果,请使用流式方法。
当客户端识别到末尾的
LIMIT 0 时,会以 JSON 格式请求列元数据。如果响应中包含行,客户端会抛出 clickhouse_connect.driver.exceptions.InternalError,且不会重新执行该查询。以 LIMIT 0 结尾的 UNION、EXCEPT 或 EXPLAIN 查询可能会出现这种情况。对于此类查询,请使用 raw_query 并指定输出格式 (例如 fmt="JSON") 。该方法返回 bytes,由您的应用程序自行解码。此行为适用于同步 HTTP、异步 HTTP 和 chDB 客户端。查询示例
基本查询
查看查询结果
使用客户端参数的查询
使用服务端参数的查询
带设置的查询
QueryResult 对象
基本 query 方法会返回一个 QueryResult 对象,包含以下公共属性:
result_rows— 按行组织的结果矩阵。result_columns— 按列组织的结果矩阵。result_set— 根据查询结果的组织方向,为result_rows或result_columns。column_names— 结果列名的 Tuple。column_types—ClickHouseType对象的 Tuple。row_count— 已 materialized 的结果行数。query_id— 为该请求报告或生成的 Query ID。空字符串表示没有可用值。summary— 从X-ClickHouse-Summary响应请求头解码得到的字典。first_item— 第一行的字典形式;如果结果为空,则为None。first_row— 第一行的序列形式;如果结果为空,则为None。column_block_stream、row_block_stream和rows_stream— 内部流上下文。请改用对应的客户端流式方法。
StreamContext API,请参见 流式查询。
使用 NumPy、Pandas 或 Arrow 处理查询结果
ClickHouse Connect 提供了针对 NumPy、Pandas 和 Arrow 数据格式的专用查询方法。有关这些方法的详细用法,包括示例、流式功能以及高级类型处理,请参阅 高级查询 (NumPy、Pandas 和 Arrow 查询) 。客户端流式查询方法
对于大型结果集的流式处理,ClickHouse Connect 提供了多种流式查询方法。有关详细信息和示例,请参阅 高级查询 (流式查询) 。客户端 insert 方法
对于向 ClickHouse 插入多条记录这一常见场景,可以使用 Client.insert 方法。它接受以下参数:
此方法返回
QuerySummary。其 summary 字典包含服务器报告的值。written_rows 是一个便捷属性,而 written_bytes() 和 query_id() 会返回对应的值。插入失败时会引发异常。
如需使用适用于 Pandas DataFrames、PyArrow Tables 和 Arrow-backed DataFrames 的专用插入方法,请参见 高级插入 (专用插入方法) 。
NumPy 数组属于合法的 Sequence of Sequences,因此可直接作为主
insert 方法的 data 参数使用,无需专用方法。示例
以下示例假设已存在一张users 表,其 schema 为 (id UInt32, name String, age UInt8)。
简单的按行插入
按列插入
使用显式指定的列类型进行插入
向特定数据库插入
文件插入
如需将数据直接从文件插入 ClickHouse 表,请参阅 高级插入 (文件插入) 。原始 API
对于需要直接访问 ClickHouse HTTP 接口且不进行类型转换的高级用例,请参阅高级用法 (原始 API) 。Python DB-API 2.0
clickhouse_connect.dbapi 模块实现了 PEP 249 规定的连接和游标接口。它声明 API 级别为 2.0、threadsafety=2 以及 paramstyle="pyformat"。该模块还提供 PEP 249 类型构造函数 Date、Time、Timestamp 和 Binary,以及 DateFromTicks、TimeFromTicks 和 TimestampFromTicks 函数。
该模块导出了 PEP 249 定义的异常层次结构:Warning、Error、InterfaceError、DatabaseError、DataError、OperationalError、IntegrityError、InternalError、ProgrammingError 和 NotSupportedError。这些异常与 clickhouse_connect.driver.exceptions 中公开的是同一批类对象,因此无论从哪个路径导入,都能捕获驱动错误。驱动特有的 StreamFailureError 仍可从 clickhouse_connect.driver.exceptions 导入,它是 OperationalError 的一种。
Cursor.execute 和 Cursor.executemany 都接受额外的 settings 和 query_formats 关键字参数。settings 用于传递 ClickHouse 设置。当语句返回行时,query_formats 会根据 ClickHouse 类型应用读取格式,其映射方式与 Client.query 相同。这两个方法还都接受仅限关键字的 pyformat_encoded 参数。其默认值 True 遵循 DB-API pyformat 约定。当语句编译器生成了原始百分号时,SQLAlchemy 方言会将其设为 False,因此应用通常不应设置它。参数化的 Cursor.executemany 操作会针对每个参数集分别执行一次,从而保留 SQL 绑定和表达式的语义。使用 HTTP 时,每个参数集都会单独发送一个请求。如果后续某个参数集执行失败,此前已完成的写入仍保持已提交状态。对于这类 executemany insert,Cursor.rowcount 为 ClickHouse 报告的 written_rows 值之和;若无法获取该值,则为 -1。通过 Cursor.execute 发送的 INSERT 语句返回 0。不含占位符的 INSERT INTO table (columns) VALUES 兼容形式会使用 Native insert。以 VALUES 结尾且不含占位符的 INSERT 若无法识别为该兼容形式,则会抛出 ProgrammingError。如需显式执行 Native 批量 insert,应用应使用 Client.insert。fetchone、fetchmany 和 fetchall 会读取当前已 materialized 的结果。
Cursor.description 会根据每个结果列的类型确定 null_ok。不可为 NULL 的类型返回 False,可为 NULL 的类型返回 True,包括 Nullable 包装器、Variant 和 Dynamic。None 表示可空性未知。当以 SELECT 或 WITH 开头的查询 (忽略前导注释) 既不返回行也不返回列元数据时,游标会执行 LIMIT 0 元数据查询来填充 description。如果该元数据查询失败,description 将保持为空。
ClickHouse 不通过此 HTTP 接口提供传统事务。Connection.commit() 和 Connection.rollback() 都是空操作。共享 connection 时,会话 ID 并发规则仍然适用。
实用类和函数
以下模块提供客户端应用程序可用的其他公开辅助工具。 已安装的软件包版本会以字符串clickhouse_connect.__version__ 的形式公开。
异常
自定义异常 (包括由clickhouse_connect.dbapi 重新导出的 DB-API 2.0 异常层次结构) 定义在 clickhouse_connect.driver.exceptions 中。DatabaseError 和 OperationalError 都会提供数值型 code attribute,用于表示 ClickHouse 错误代码;还会提供 name attribute,用于表示符号名称,例如 UNKNOWN_TABLE,这样应用程序就可以根据 exc.code 进行分支判断,而不必解析消息。即使禁用了 show_clickhouse_errors,code 也会被设置;而 name 则要求提供错误详情 (True 或 "scrub")。两者在不可用时 (例如发生传输错误时) 都会是 None。当应允许最终用户查看 SQL 错误但不显示 host 或服务器版本信息时,请使用 show_clickhouse_errors="scrub"。该设置还控制流中 StreamFailureError 消息和通用传输消息。它仅控制 str(exc)。传输错误仍会作为 __cause__ 附加,且 tracebacks 可能包含原始 host、URL 或 library 错误文本。
ClickHouse SQL 实用工具
clickhouse_connect.driver.binding 模块中的函数和 DT64Param 类可用于正确构造并转义 ClickHouse SQL 查询。类似地,clickhouse_connect.driver.parser 模块中的函数可用于解析 ClickHouse 数据类型名称。