底层 API
客户端 raw_query 方法
Client.raw_query 方法允许通过客户端连接直接使用 ClickHouse HTTP 查询接口。返回值是一个未经处理的 bytes 对象。它通过极简接口提供了便捷封装,支持参数绑定、错误处理、重试和 settings 管理:
| 参数 | 类型 | 默认值 | 说明 |
|---|---|---|---|
| query | str | Required | 任何有效的 ClickHouse 查询 |
| parameters | dict or iterable | None | 请参见参数说明。 |
| settings | dict | None | 请参见settings 说明。 |
| fmt | str | None | 结果字节使用的 ClickHouse 输出格式。 (如果未指定,ClickHouse 使用 TSV) |
| use_database | bool | True | 在查询上下文中使用分配给 ClickHouse Connect 客户端的数据库 |
| external_data | ExternalData | None | 一个 ExternalData 对象,包含可供查询使用的文件或二进制数据。请参见高级查询 (外部数据) |
bytes 对象由调用方负责。请注意,Client.query_arrow 只是对此方法的一个轻量封装,使用的是 ClickHouse Arrow 输出格式。
客户端 raw_stream 方法
Client.raw_stream 方法与 raw_query 方法的 API 相同,但它返回一个 io.IOBase 对象,可作为 bytes 对象的生成器或流来源使用。目前,query_arrow_stream 方法正在使用它。
Client raw_insert 方法
Client.raw_insert 方法允许通过客户端连接直接插入 bytes 对象或 bytes 对象生成器。由于它不会对插入载荷进行任何处理,因此性能非常高。该方法提供了用于指定设置和插入格式的选项:
| 参数 | 类型 | 默认值 | 描述 |
|---|---|---|---|
| table | str | 必填 | 简单表名或带数据库限定名的表名 |
| column_names | Sequence[str] | None | 插入块的列名。如果 fmt 参数不包含列名,则为必填项 |
| insert_block | str, bytes, Generator[bytes], BinaryIO | 必填 | 要插入的数据。字符串将使用客户端编码进行编码。 |
| settings | dict | None | 请参见 settings 描述。 |
| fmt | str | None | insert_block 字节的 ClickHouse 输入格式。 (如果未指定,ClickHouse 使用 TSV) |
insert_block 采用指定的格式,并使用指定的压缩方法。ClickHouse Connect 会将这些原始插入用于文件上传和 PyArrow 表,并将解析工作交由 ClickHouse 服务器 处理。
将查询结果保存为文件
raw_stream 方法直接将文件从 ClickHouse 流式写入本地文件系统。例如,如果你想将某个查询的结果保存为 CSV 文件,可以使用以下代码片段:
output.csv 文件,内容如下:
多线程、多进程和异步/事件驱动用例
QueryContext 或 InsertContext 对象中维护状态,这些辅助对象本身并不是线程安全的,因此不应在多个处理流之间共享。有关上下文对象的更多讨论,请参见 QueryContexts 和 InsertContexts 部分。
此外,对于同时有两个或更多查询和/或插入“在进行中”的应用程序,还需要注意另外两个方面。第一是与查询/插入关联的 ClickHouse“会话”,第二是 ClickHouse Connect Client 实例使用的 HTTP 连接池。
AsyncClient 包装器
Client 提供了一个异步包装层,因此可以在 asyncio 环境中使用该客户端。
要获取 AsyncClient 实例,可以使用 get_async_client 工厂函数;它接受的参数与标准 get_client 相同:
AsyncClient 与标准 Client 具有相同的方法和参数,但在适用情况下,这些方法会以协程形式提供。在内部,Client 中执行 I/O 操作的方法会被包装到 run_in_executor 调用中。
使用 AsyncClient 包装器时,多线程性能会有所提升,因为在等待 I/O 操作完成期间,执行线程和 GIL 都会被释放。
注意:与常规 Client 不同,AsyncClient 默认会强制将 autogenerate_session_id 设为 False。
另请参阅:run_async 示例。
管理 ClickHouse 会话 ID
- 将特定的 ClickHouse settings 关联到多个查询 (请参见用户 settings) 。ClickHouse
SET命令用于在用户 会话 范围内更改 settings。 - 跟踪临时表。
Client 实例执行的每个查询都会使用该客户端的 会话 ID。使用单个客户端时,SET 语句和临时表都能按预期工作。但是,ClickHouse 服务器 不允许在同一个 会话 中执行并发查询 (如果尝试这样做,客户端会引发 ProgrammingError) 。对于需要执行并发查询的应用程序,请使用以下模式之一:
- 为每个需要 会话 隔离的线程/进程/event handler 创建单独的
Client实例。这样可以保留每个客户端各自的 会话 状态 (临时表和SET值) 。 - 如果不需要共享 会话 状态,请在调用
query、command或insert时,通过settingsargument 为每个查询指定唯一的session_id。 - 通过在创建客户端之前设置
autogenerate_session_id=False,禁用共享客户端上的 会话 (或者直接将其传递给get_client) 。
autogenerate_session_id=False 传递给 get_client(...)。
在这种情况下,ClickHouse Connect 不会发送 session_id;服务器不会将不同的请求视为属于同一会话。临时表和会话级设置不会在请求之间保留。
自定义 HTTP 连接池
urllib3 连接池来管理与服务器之间的底层 HTTP 连接。默认情况下,所有客户端实例共享同一个连接池,这对于绝大多数使用场景已经足够。该默认连接池会为应用程序使用的每个 ClickHouse 服务器维护最多 8 个 HTTP Keep-Alive 连接。
对于大型多线程应用,使用独立的连接池可能更合适。可以通过主 clickhouse_connect.get_client 函数的 pool_mgr 关键字参数提供自定义连接池:
urllib3 文档。