> ## Documentation Index
> Fetch the complete documentation index at: https://private-7c7dfe99-parallel-read-in-order-multi-part.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

> ClickHouse Connect 驱动 API

# ClickHouse Connect 驱动 API

<Note>
  对于客户端工厂以及具有大量可选参数的方法，建议使用关键字参数传参。

  *此处未文档说明的方法不属于 API 的一部分，后续可能会被移除或更改。*
</Note>

<h2 id="client-initialization">
  客户端初始化
</h2>

使用 `clickhouse_connect.get_client` 创建同步 `Client`；或者安装 `async` 扩展，并通过 await 调用 `clickhouse_connect.get_async_client` 来创建原生 `AsyncClient`。

<h3 id="connection-arguments">
  连接参数
</h3>

| 参数 | 类型 | 默认值 | 说明 |
| - | - | - | - |
| `interface` | str | `"http"` | `"http"` 或 `"https"`。同步工厂也接受 Experimental `"chdb"` 后端。 |
| `host` | str | `"localhost"` | ClickHouse server 的主机名或 IP 地址。 |
| `port` | int 或 None | `8123` 或 `8443` | HTTP 默认为 8123，HTTPS 默认为 8443。传入 `None` 表示使用默认值。 |
| `username` | str 或 None | `"default"` | ClickHouse 用户名。也可使用别名 `user` 和 `user_name`。 |
| `password` | str | `""` | `username` 的密码。请勿将用户名/密码身份验证与标记身份验证结合使用。 |
| `access_token` | str 或 None | `None` | ClickHouse Cloud JWT 访问令牌。与 `token_provider` 以及用户名/密码身份验证互斥。 |
| `token_provider` | callable 或 None | `None` | 可调用对象，用于在初始请求时以及身份验证被拒绝后提供 JWT。异步提供函数可与 `get_async_client` 搭配使用。 |
| `database` | str 或 None | 用户默认 | 默认数据库。传入 `None` 则使用服务器为该用户设置的默认数据库。 |
| `secure` | bool 或 str | `False` | 启用 HTTPS/TLS。`interface="https"` 也会启用 HTTPS；如果未设置 `interface`，使用端口 443 或 8443 也会启用 HTTPS。 |
| `dsn` | str 或 None | `None` | 连接 URL。显式关键字参数的优先次序高于从 DSN 解析出的值。对凭据和数据库名称中的保留字符进行百分比编码。 |
| `settings` | dict 或 None | `None` | 应用于客户端每个请求的 ClickHouse 设置。 |
| `headers` | dict 或 None | `None` | 应用于所有请求 (包括客户端初始化) 的 HTTP 请求头。用户自定义请求头会在驱动默认请求头之后应用，并可覆盖这些默认值。 |
| `compress` | bool 或 str | `True` | 启用压缩，或指定 `"lz4"`、`"zstd"`、`"br"` 或 `"gzip"`。请参阅[压缩](/zh/integrations/language-clients/python/additional-options#compression)。 |
| `query_limit` | int | `0` | 会为符合条件的查询追加默认行数限制。0 表示不限制。对于大型结果，建议以流式方式处理，而不是将其全部物化到内存中。 |
| `query_retries` | int | `2` | 用于可重试读取失败的重试次数预算。命令和插入操作通常不进行重试，因为重放可能会导致副作用重复发生。 |
| `connect_timeout` | 同步为 int，异步为 float | `10` | 建立新连接的超时时间，单位为秒，不包括等待连接池空闲槽位的时间。异步客户端支持小数秒。 |
| `send_receive_timeout` | 同步为 int，异步为 float | `300` | 套接字读取超时时间，单位为秒。异步客户端支持小数秒。 |
| `client_name` | str 或 None | `None` | 添加到 HTTP User-Agent 前的前缀，用于在 `system.query_log` 中进行标识。 |
| `session_id` | str 或 None | 同步时自动生成 | 显式指定的 ClickHouse session ID。同步客户端默认会生成一个；异步客户端则不会。 |
| `autogenerate_session_id` | Bool 或 None | 同步时遵循全局设置，异步时为 `False` | 覆盖自动生成 session ID 的设置。对于会被并发操作共享的客户端，除非需要保留会话状态，否则应禁用此功能。 |
| `autogenerate_query_id` | bool 或 None | 全局设置，`True` | 覆盖自动生成 UUID 查询 ID 的行为。 |
| `http_proxy` | str 或 None | 环境变量/默认值 | 每个客户端的 HTTP 代理地址。 |
| `https_proxy` | str 或 None | 环境变量/默认值 | 每个客户端的 HTTPS 代理地址。 |
| `pool_mgr` | `urllib3.PoolManager` 或 None | 进程内共享 | 仅用于同步客户端的自定义连接池管理器。 |
| `tz_source` | str 或 None | `"auto"` | 用于没有时区元数据的列的后备时区来源：`"auto"`、`"server"` 或 `"local"`。 |
| `tz_mode` | str 或 None | `"naive_utc"` | UTC 结果处理策略：`"naive_utc"`、`"aware"` 或 `"schema"`。参见 [时区](/zh/integrations/language-clients/python/advanced-querying#time-zones)。 |
| `show_clickhouse_errors` | bool、布尔值字符串、`"scrub"` 或 None | `True` | 控制服务器错误、传输错误和流中 `StreamFailureError` 的 `str(exc)`。`True` 会包含请求 URL 和服务器版本尾注。`"scrub"` 会保留 SQL 错误文本和符号名称，但会移除主机名/URL 及 `(version ...)` 尾注。`False` 会返回通用消息 (服务器错误仍会设置 `code`) 。接受布尔值字符串。其他字符串会引发 `ProgrammingError`。对于传输错误，`__cause__` 和回溯信息仍包含原始传输异常。 |
| `proxy_path` | str | `""` | 通过代理路由时，添加到服务器 URL 的路径前缀。 |
| `form_encode_query_params` | bool | `False` | 始终将查询参数放入采用表单编码的请求体中。即使该值为 false，较大的非二进制参数载荷也会自动移入请求体中。 |
| `native_codec` | str 或 None | 全局设置，`"python"` | 用于客户端管理的 Native 格式流量的 Experimental 编解码器：`"python"`、`"rust"` 或 `"rust_strict"`。Rust 相关取值需要 `clickhouse-connect-core` wheel 包。请参阅 [Rust codec](/zh/integrations/language-clients/python/rust-codec)。 |
| `rename_response_column` | str 或 None | `None` | 列重命名策略：`"remove_prefix"`、`"to_camelcase"`、`"to_camelcase_without_prefix"`、`"to_underscore"` 或 `"to_underscore_without_prefix"`。 |

同步和异步 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 后端](#embedded-chdb-backend)。

<h3 id="httpstls-arguments">
  HTTPS/TLS 参数
</h3>

| 参数 | 类型 | 默认值 | 描述 |
| - | - | - | - |
| `verify` | bool or str | `True` | 验证服务器证书和主机名。`verify="proxy"` 会启用代理 TLS 模式。 |
| `ca_cert` | str or None | `None` | CA 证书包路径。使用 `"certifi"` 可选择 `certifi` 包附带的证书包。 |
| `client_cert` | str or None | `None` | PEM 客户端证书；在需要时应包含中间证书。 |
| `client_cert_key` | str or None | `None` | 如果私钥未包含在 `client_cert` 中，则指定其私钥路径。 |
| `server_host_name` | str or None | `None` | 当 TLS 证书/SNI 主机名与 `host` 不同时使用，例如通过隧道或私网端点访问时。 |
| `tls_mode` | str or None | `None` | `"mutual"` 使用 ClickHouse 双向 TLS 身份验证。`"proxy"` 和 `"strict"` 会在 TLS 层发送证书，但不会启用 ClickHouse 证书身份验证请求头。默认值 `None` 在提供客户端证书时的行为与 `"mutual"` 相同。 |

<h3 id="settings-argument">
  Settings 参数
</h3>

最后，`get_client` 的 `settings` 参数用于在每次客户端请求时，向服务器传递额外的 ClickHouse 设置。请注意，在大多数情况下，具有 *readonly*=*1* 权限的用户无法修改随查询一起发送的设置，因此 ClickHouse Connect 会在最终请求中丢弃此类设置，并记录一条警告。以下设置仅适用于 ClickHouse Connect 使用的 HTTP 查询/会话，不属于通用 ClickHouse 设置文档中的内容。

| Setting | Description |
| - | - |
| `buffer_size` | 服务器端 HTTP 响应缓冲区大小，以字节为单位。 |
| `session_id` | 用于关联相关请求的会话 ID。临时表和会话状态需要此项。 |
| `compress` | 请求服务器压缩 HTTP 响应。通常由客户端压缩选项控制。 |
| `decompress` | 告知服务器解压请求体。用于预先压缩的原始插入。 |
| `quota_key` | 与该请求关联的配额键。 |
| `session_check` | 请求服务器验证会话是否存在。 |
| `session_timeout` | 会话非活动超时，单位为秒。 |
| `wait_end_of_query` | 在服务器端缓冲完整响应。客户端会在需要非流式摘要信息时设置此项。 |
| `query_id` | 该请求的显式查询 ID。 |
| `client_protocol_version` | Native 格式客户端协议能力级别。通常会自动协商。 |
| `role` | 该请求/会话使用的 ClickHouse role。 |

有关可随每个查询一起发送的其他 ClickHouse 设置，请参阅 [ClickHouse 文档](/zh/reference/settings/session-settings)。

<h3 id="client-creation-examples">
  客户端创建示例
</h3>

* 在不传入任何参数的情况下，ClickHouse Connect 客户端会使用 default 用户且不设置密码，连接到 `localhost` 的默认 HTTP 端口：

```python theme={null}
import clickhouse_connect

client = clickhouse_connect.get_client()
print(client.server_version)
```

* 连接到安全 (HTTPS) 的外部 ClickHouse 服务器

```python theme={null}
import clickhouse_connect

client = clickhouse_connect.get_client(
    host="play.clickhouse.com",
    secure=True,
    port=443,
    username="play",
    password="clickhouse",
)
print(client.command("SELECT timezone()"))
```

* 使用会话 ID、其他自定义连接参数以及 ClickHouse 设置进行连接。

```python theme={null}
import clickhouse_connect

client = clickhouse_connect.get_client(
    host="play.clickhouse.com",
    username="play",
    password="clickhouse",
    port=443,
    secure=True,
    session_id="example_session_1",
    connect_timeout=15,
    database="github",
    settings={"distributed_ddl_task_timeout": 300},
)
print(client.database)
# Output: github
```

<h3 id="embedded-chdb-backend">
  嵌入式 chDB 后端
</h3>

安装 `clickhouse-connect[chdb]` 以使用 Experimental 的进程内 chDB 后端。它提供同步客户端的查询、插入、流式和 Arrow 方法：

```python theme={null}
import clickhouse_connect

with clickhouse_connect.get_client(interface="chdb") as client:
    result = client.query("SELECT sum(number) FROM numbers(10)")
    print(result.first_row)
    # Output: (45,)
```

默认使用的是内存数据库。传入 `path="/data/my_chdb"` 或使用 `dsn="chdb:///data/my_chdb"` 可启用持久化存储。该后端每个进程只允许使用一个 engine 路径，并且不支持 `get_async_client` 或外部数据。

<h2 id="client-lifecycle-and-best-practices">
  客户端生命周期和最佳实践
</h2>

创建 ClickHouse Connect 客户端的开销较大，因为这需要建立连接、获取服务器元数据并初始化设置。请遵循以下最佳实践以获得最佳性能：

<h3 id="core-principles">
  核心原则
</h3>

* **复用客户端**：在应用启动时创建一次客户端，并在整个应用生命周期内重复使用
* **避免频繁创建**：不要为每个查询或请求都新建客户端
* **正确清理**：应用关闭时务必关闭客户端，以释放连接池资源
* **尽可能共享**：单个客户端可通过其连接池处理大量并发查询 (参见下方的线程说明)

<h3 id="basic-patterns">
  基本原则
</h3>

复用同一个客户端：

```python theme={null}
import clickhouse_connect

# Create once at startup
client = clickhouse_connect.get_client(
    host="my-host",
    username="default",
    password="password",
)

# Reuse for all queries
for i in range(1000):
    result = client.query("SELECT count() FROM users")

# Close on shutdown
client.close()
```

避免反复创建客户端：

```python theme={null}
# BAD: Creates 1000 clients with expensive initialization overhead
for i in range(1000):
    client = clickhouse_connect.get_client(
        host="my-host",
        username="default",
        password="password",
    )
    result = client.query("SELECT count() FROM users")
    client.close()
```

<h3 id="multi-threaded-applications">
  多线程应用
</h3>

<Warning>
  使用会话 ID 时，客户端实例**不具备线程安全性**。默认情况下，客户端会自动生成一个会话 ID。如果客户端检测到本地存在重叠，通过同一客户端在同一会话中并发执行查询会引发 `ProgrammingError`。命名会话的状态以及服务器端的会话重叠检查仅限于单个 ClickHouse 服务器进程，因此在 ClickHouse Cloud 或其他负载均衡部署中，固定的 `session_id` 既不是分布式状态，也不能充当分布式互斥锁。
</Warning>

要在线程间安全地共享客户端：

```python theme={null}
import clickhouse_connect
import threading

# Option 1: Disable sessions (recommended for shared clients)
client = clickhouse_connect.get_client(
    host="my-host",
    username="default",
    password="password",
    autogenerate_session_id=False,
)

def worker(thread_id):
    # All threads can now safely use the same client
    result = client.query(f"SELECT {thread_id}")
    print(f"Thread {thread_id}: {result.result_rows[0][0]}")

threads = [threading.Thread(target=worker, args=(i,)) for i in range(10)]
for t in threads:
    t.start()
for t in threads:
    t.join()

client.close()
```

**会话的替代方案：** 如果你需要使用会话 (例如用于临时表) ，请为每个线程单独创建一个客户端：

```python theme={null}
def worker(thread_id):
    # Each thread gets its own client with isolated session
    client = clickhouse_connect.get_client(
        host="my-host",
        username="default",
        password="password",
    )
    client.command("CREATE TEMPORARY TABLE temp (id UInt32) ENGINE = Memory")
    # ... use temp table ...
    client.close()
```

<h3 id="proper-cleanup">
  正确清理
</h3>

务必在关闭时关闭客户端。请注意，只有当客户端拥有自己的连接池管理器时 (例如，使用自定义 TLS/代理选项创建时) ，`client.close()` 才会释放客户端并关闭池化的 HTTP 连接。对于默认的共享连接池，请使用 `client.close_connections()` 主动清理套接字；否则，连接会在空闲超时后以及进程退出时自动回收。

```python theme={null}
client = clickhouse_connect.get_client(
    host="my-host",
    username="default",
    password="password",
)
try:
    result = client.query("SELECT 1")
finally:
    client.close()
```

或者使用上下文管理器：

```python theme={null}
with clickhouse_connect.get_client(
    host="my-host",
    username="default",
    password="password",
) as client:
    result = client.query("SELECT 1")
```

<h3 id="when-to-use-multiple-clients">
  何时使用多个客户端
</h3>

多个客户端适用于以下情况：

* **不同的服务器**：每个 ClickHouse 服务器或集群使用一个客户端
* **不同的凭据**：针对不同用户或不同访问级别分别使用独立客户端
* **不同的数据库**：当你需要使用多个数据库时
* **隔离的会话**：当你需要为临时表或会话级设置使用独立会话时
* **按线程隔离**：当线程需要独立会话时 (如上所示)

<h2 id="common-method-arguments">
  常用方法参数
</h2>

多个客户端方法会使用通用的 `parameters` 和/或 `settings` 参数。下面将介绍这些关键字参数。

<h3 id="parameters-argument">
  Parameters 参数
</h3>

ClickHouse Connect 客户端的 `query*` 和 `command` 方法都接受一个可选的 `parameters` 关键字参数，用于将 Python 表达式绑定到 ClickHouse 值表达式。提供两种绑定方式。

<h4 id="server-side-binding">
  服务器端绑定
</h4>

ClickHouse 支持对查询值使用[服务器端绑定](/zh/concepts/features/interfaces/client#cli-queries-with-parameters)。绑定的值会作为 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 字典、日期时间值和字符串值的服务器端绑定

```python theme={null}
import datetime

my_date = datetime.datetime(2022, 10, 1, 15, 20, 5)

parameters = {
    "table": "my_table",
    "v1": my_date,
    "v2": "a string with a single quote'",
}
client.query(
    "SELECT * FROM {table:Identifier} "
    "WHERE date >= {v1:DateTime} AND string ILIKE {v2:String}",
    parameters=parameters,
)
```

这相当于：

```sql theme={null}
SELECT *
FROM my_table
WHERE date >= '2022-10-01 15:20:05'
  AND string ILIKE 'a string with a single quote\''
```

服务器端绑定适用于 `SELECT` 查询和 `INSERT ... VALUES` 语句。如需批量插入大量普通数据，建议使用 `Client.insert`。

<h4 id="client-side-binding">
  客户端绑定
</h4>

ClickHouse Connect 也支持客户端参数绑定，这样在生成模板化 SQL 查询时会更灵活。对于客户端绑定，`parameters` 参数应为字典或序列。客户端绑定使用 Python 的["printf" 风格](https://docs.python.org/3/library/stdtypes.html#old-string-formatting)字符串格式化进行参数替换。

请注意，与服务器端绑定不同，客户端绑定不适用于数据库标识符，例如 database、表或列名，因为 Python 风格的格式化无法区分不同类型的字符串，而这些字符串需要采用不同的格式化方式 (数据库标识符使用反引号或双引号，数据值使用单引号) 。

* 使用 Python Dictionary、日期时间 值和字符串转义的示例

```python theme={null}
import datetime

my_date = datetime.datetime(2022, 10, 1, 15, 20, 5)

parameters = {"v1": my_date, "v2": "a string with a single quote'"}
client.query(
    "SELECT * FROM my_table "
    "WHERE date >= %(v1)s AND string ILIKE %(v2)s",
    parameters=parameters,
)
```

这会在服务器端生成以下查询：

```sql theme={null}
SELECT *
FROM my_table
WHERE date >= '2022-10-01 15:20:05'
  AND string ILIKE 'a string with a single quote\''
```

* Python Sequence (Tuple) 、Float64 和 IPv4Address 示例

```python theme={null}
import ipaddress

parameters = (35200.44, ipaddress.IPv4Address(0x443d04fe))
client.query(
    "SELECT * FROM some_table WHERE metric >= %s AND ip_address = %s",
    parameters=parameters,
)
```

这会在服务器端生成以下查询：

```sql theme={null}
SELECT *
FROM some_table
WHERE metric >= 35200.44
  AND ip_address = '68.61.4.254'
```

<Note>
  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 对象](/zh/integrations/language-clients/python/advanced-inserting#timezone-naive-datetime-objects)。

  向 `Date` 和 `Date32` 列执行原生插入时，会直接使用 Python `datetime` 值自身的日历日期，不进行时区转换。如果插入和查询参数需要使用相同的日历日期，请显式传入 `value.date()`。请参阅[Date 和 Date32 值](/zh/integrations/language-clients/python/advanced-inserting#date-and-date32-values)。

  对于服务器端的 `{value:DateTime64(precision)}` 占位符，已声明的类型会自动保留子秒级精度，在 `Array` 和 `Tuple` 提示中也是如此。

  客户端 `%s` 绑定没有声明类型。如果必须以子秒级精度进行格式化，请将 `datetime` 封装在 `DT64Param` 中：

  ```python theme={null}
  from datetime import datetime

  from clickhouse_connect.driver.binding import DT64Param

  query = "SELECT toDateTime64(%s, 6)"
  parameters = [DT64Param(datetime.now())]
  client.query(query, parameters=parameters)
  ```

  为保持向后兼容，如果字典参数名以 `_64` 结尾，即使查询中不存在这个带该后缀的确切名称，也会请求按 DateTime64 格式进行格式化。

  `datetime.time` 或 `datetime.timedelta` 参数会格式化为 `[-]HH:MM:SS[.ffffff]` 字面量，适用于 ClickHouse `Time` 和 `Time64` 列；无论使用哪种绑定方式，也包括 `Array` 和 `Tuple` 值中的参数。客户端会添加引号，因此不要在查询中为占位符加引号。`timedelta` 可以为负数，也可以超过 24 小时。pandas `Timedelta` 会保留纳秒，并为 `Time64(9)` 格式化为九位小数部分。带时区信息的 `time` 中的时区信息会被忽略，因为 ClickHouse `Time` 没有时区。
</Note>

<h3 id="settings-argument-1">
  Settings 参数
</h3>

所有关键的 ClickHouse Connect 客户端 "insert" 和 "select" 方法都接受一个可选的 `settings` 关键字参数，用于为包含的 SQL 语句传递 ClickHouse 服务器的[用户设置](/zh/reference/settings/session-settings)。`settings` 参数应为一个字典。每一项都应包含一个 ClickHouse 设置名称及其对应的值。请注意，这些值在作为查询参数发送到服务器时会被转换为字符串。

与客户端级别的设置一样，ClickHouse Connect 会丢弃任何被服务器标记为 *readonly*=*1* 的设置，并记录相应的日志消息。仅适用于通过 ClickHouse HTTP 接口 发起查询的设置始终有效。这些设置在 `get_client` [API](#settings-argument) 下有说明。

使用 ClickHouse 设置的示例：

```python theme={null}
settings = {
    "merge_tree_min_rows_for_concurrent_read": 65535,
    "session_id": "session_1234",
    "use_skip_indexes": False,
}
client.query(
    "SELECT event_type, sum(timeout) "
    "FROM event_errors WHERE event_time > '2022-08-01'",
    settings=settings,
)
```

<h2 id="client-command-method">
  Client `command` 方法
</h2>

对于不返回表格数据集的语句，或者返回单个基本类型值或单行的查询，请使用 `Client.command`。根据响应内容，它会返回字符串、整数、字符串序列或 `QuerySummary`。如果读取操作产生空结果集，则返回空字符串。

| Parameter | Type | Default | Description |
| - | - | - | - |
| cmd | str | *Required* | 一条返回单个值或单行值的 ClickHouse SQL 语句。 |
| parameters | dict or sequence | *None* | 请参阅[参数说明](#parameters-argument)。 |
| data | str or bytes | *None* | 可选数据，作为 POST 请求体随命令一同发送。 |
| settings | dict | *None* | 请参阅[settings 说明](#settings-argument-1)。 |
| use\_database | bool | True | 使用客户端数据库 (在创建客户端时指定) 。False 表示该命令将使用当前连接用户在 ClickHouse 服务器上的默认数据库。 |
| external\_data | ExternalData | *None* | 一个 `ExternalData` 对象，包含供查询使用的文件或二进制数据。请参阅 [高级查询 (外部数据) ](/zh/integrations/language-clients/python/advanced-querying#external-data) |
| transport\_settings | dict | *None* | 可选字典，包含要随此请求发送的 HTTP 请求头。每个键值对都会作为一个 HTTP 请求头添加 (例如 `{'X-Custom-Header': 'value'}`) 。这对于代理身份验证、请求链路追踪，或传递中间基础设施所需的请求头非常有用。 |

<h3 id="command-examples">
  命令示例
</h3>

<h4 id="ddl-statements">
  DDL 语句
</h4>

```python theme={null}
import clickhouse_connect

client = clickhouse_connect.get_client()

# Create a table. A successful DDL returns QuerySummary.
summary = client.command(
    "CREATE TABLE test_command "
    "(col_1 String, col_2 DateTime) "
    "ENGINE MergeTree ORDER BY tuple()"
)
print(summary.query_id())

# Show table definition
result = client.command("SHOW CREATE TABLE test_command")
print(result)
# Output:
# CREATE TABLE default.test_command
# (
#     `col_1` String,
#     `col_2` DateTime
# )
# ENGINE = MergeTree
# ORDER BY tuple()

# Drop table
client.command("DROP TABLE test_command")
```

<h4 id="simple-queries-returning-single-values">
  返回单个值的简单查询
</h4>

```python theme={null}
import clickhouse_connect

client = clickhouse_connect.get_client()

# Single value result
count = client.command("SELECT count() FROM system.tables")
print(count)

# Server version
version = client.command("SELECT version()")
print(version)
```

<h4 id="commands-with-parameters">
  带参数的命令
</h4>

```python theme={null}
import clickhouse_connect

client = clickhouse_connect.get_client()

# 使用客户端参数
table_name = "system"
result = client.command(
    "SELECT count() FROM system.tables WHERE database = %(db)s",
    parameters={"db": table_name}
)

# 使用服务端参数
result = client.command(
    "SELECT count() FROM system.tables WHERE database = {db:String}",
    parameters={"db": "system"}
)
```

<h4 id="commands-with-settings">
  带设置的命令
</h4>

```python theme={null}
import clickhouse_connect

client = clickhouse_connect.get_client()

# 使用特定设置执行命令
result = client.command(
    "OPTIMIZE TABLE large_table FINAL",
    settings={"optimize_throw_if_noop": 1}
)
```

<h2 id="client-query-method">
  Client `query` 方法
</h2>

`Client.query` 以 ClickHouse Native 格式检索表格数据集，并返回一个 `QueryResult`。访问结果属性时，会将完整结果 materialized。对于不应保存在内存中的结果，请使用流式方法。

<Note>
  当客户端识别到末尾的 `LIMIT 0` 时，会以 JSON 格式请求列元数据。如果响应中包含行，客户端会抛出 `clickhouse_connect.driver.exceptions.InternalError`，且不会重新执行该查询。以 `LIMIT 0` 结尾的 `UNION`、`EXCEPT` 或 `EXPLAIN` 查询可能会出现这种情况。

  对于此类查询，请使用 [`raw_query`](/zh/integrations/language-clients/python/advanced-usage#client-rawquery-method) 并指定输出格式 (例如 `fmt="JSON"`) 。该方法返回 `bytes`，由您的应用程序自行解码。此行为适用于同步 HTTP、异步 HTTP 和 chDB 客户端。
</Note>

| 参数 | 类型 | 默认值 | 描述 |
| - | - | - | - |
| `query` | str | 必填 | 返回表格结果的 ClickHouse 查询，最常见的是 `SELECT` 或 `DESCRIBE`。如果由 `context` 提供，则可省略。 |
| `parameters` | dict 或序列 | `None` | 请参见 [Parameters 参数](#parameters-argument)。 |
| `settings` | dict | `None` | 请参见 [Settings 参数](#settings-argument-1)。 |
| `query_formats` | dict | `None` | 按 ClickHouse 类型指定读取格式。请参见 [Read formats](/zh/integrations/language-clients/python/advanced-querying#read-formats)。 |
| `column_formats` | dict | `None` | 按结果列指定读取格式，包括 Nested type 格式映射。 |
| `encoding` | str | `None` | String 列编码。默认为 UTF-8。 |
| `use_none` | bool | `True` | 对 SQL NULL 返回 `None`。当为 false 时，返回该类型的默认空值。NumPy/Pandas 方法会选择偏重性能的默认值。 |
| `column_oriented` | bool | `False` | 将结果按列而非按行组织。 |
| `use_numpy` | bool | `False` | 将兼容的结果列读取到 `QueryResult` 内部的 NumPy 数组中。如果期望结果是单个 NumPy 矩阵，优先使用 `query_np`。 |
| `max_str_len` | int | `0` | 配合 `use_numpy` 使用时，对长度不超过此值的 String 列使用固定宽度的 Unicode dtype。为零时使用对象数组。 |
| `context` | `QueryContext` | `None` | 可复用的查询上下文。显式传入的方法参数会覆盖上下文值。 |
| `query_tz` | str 或 `tzinfo` | `None` | 应用于所有 `DateTime` 和 `DateTime64` 结果列的时区。 |
| `column_tzs` | dict | `None` | 按列设置的时区映射。 |
| `external_data` | `ExternalData` | `None` | 外部文件或二进制数据。请参见 [External data](/zh/integrations/language-clients/python/advanced-querying#external-data)。 |
| `transport_settings` | dict | `None` | 添加到此请求的 HTTP 请求头。 |
| `tz_mode` | str | 客户端默认值 | 针对 `"naive_utc"`、`"aware"` 或 `"schema"` 时区处理方式的单次查询覆盖设置。 |

<h3 id="query-examples">
  查询示例
</h3>

<h4 id="basic-query">
  基本查询
</h4>

```python theme={null}
import clickhouse_connect

client = clickhouse_connect.get_client()

# Simple SELECT query
result = client.query(
    "SELECT number, toString(number) AS label FROM numbers(3)"
)

# Access results as rows
for row in result.result_rows:
    print(row)
# Output:
# (0, '0')
# (1, '1')
# (2, '2')

# Access column names and types
print(result.column_names)
# Output: ('number', 'label')
print([col_type.name for col_type in result.column_types])
# Output: ['UInt64', 'String']
```

<h4 id="accessing-query-results">
  查看查询结果
</h4>

```python theme={null}
import clickhouse_connect

client = clickhouse_connect.get_client()

result = client.query("SELECT number, toString(number) AS str FROM system.numbers LIMIT 3")

# Row-oriented access (default)
print(result.result_rows)
# Output: [(0, '0'), (1, '1'), (2, '2')]

# Column-oriented access
print(result.result_columns)
# Output: [[0, 1, 2], ['0', '1', '2']]

# Named results (list of dictionaries)
for row_dict in result.named_results():
    print(row_dict)
# Output:
# {'number': 0, 'str': '0'}
# {'number': 1, 'str': '1'}
# {'number': 2, 'str': '2'}

# First row as dictionary
print(result.first_item)
# Output: {'number': 0, 'str': '0'}

# First row as tuple
print(result.first_row)
# Output: (0, '0')
```

<h4 id="query-with-client-side-parameters">
  使用客户端参数的查询
</h4>

```python theme={null}
import clickhouse_connect

client = clickhouse_connect.get_client()

# 使用字典参数（printf 风格）
query = "SELECT * FROM system.tables WHERE database = %(db)s AND name LIKE %(pattern)s"
parameters = {"db": "system", "pattern": "%query%"}
result = client.query(query, parameters=parameters)

# 使用 Tuple 参数
query = "SELECT * FROM system.tables WHERE database = %s LIMIT %s"
parameters = ("system", 5)
result = client.query(query, parameters=parameters)
```

<h4 id="query-with-server-side-parameters">
  使用服务端参数的查询
</h4>

```python theme={null}
import clickhouse_connect

client = clickhouse_connect.get_client()

# 服务器端绑定（更安全，SELECT 查询性能更佳）
query = "SELECT * FROM system.tables WHERE database = {db:String} AND name = {tbl:String}"
parameters = {"db": "system", "tbl": "query_log"}

result = client.query(query, parameters=parameters)
```

<h4 id="query-with-settings">
  带设置的查询
</h4>

```python theme={null}
import clickhouse_connect

client = clickhouse_connect.get_client()

# 在查询中传递 ClickHouse 设置
result = client.query(
    "SELECT sum(number) FROM numbers(1000000)",
    settings={
        "max_block_size": 100000,
        "max_execution_time": 30
    }
)
```

<h3 id="the-queryresult-object">
  `QueryResult` 对象
</h3>

基本 `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，请参见 [流式查询](/zh/integrations/language-clients/python/advanced-querying#streaming-queries)。

<h2 id="consuming-query-results-with-numpy-pandas-or-arrow">
  使用 NumPy、Pandas 或 Arrow 处理查询结果
</h2>

ClickHouse Connect 提供了针对 NumPy、Pandas 和 Arrow 数据格式的专用查询方法。有关这些方法的详细用法，包括示例、流式功能以及高级类型处理，请参阅 [高级查询 (NumPy、Pandas 和 Arrow 查询) ](/zh/integrations/language-clients/python/advanced-querying#numpy-pandas-and-arrow-queries)。

<h2 id="client-streaming-query-methods">
  客户端流式查询方法
</h2>

对于大型结果集的流式处理，ClickHouse Connect 提供了多种流式查询方法。有关详细信息和示例，请参阅 [高级查询 (流式查询) ](/zh/integrations/language-clients/python/advanced-querying#streaming-queries)。

<h2 id="client-insert-method">
  客户端 `insert` 方法
</h2>

对于向 ClickHouse 插入多条记录这一常见场景，可以使用 `Client.insert` 方法。它接受以下参数：

| 参数 | Type | 默认值 | 说明 |
| - | - | - | - |
| `table` | str | Required | 目标表。允许使用带数据库限定的名称。如果由 `context` 提供，则可省略。 |
| `data` | Sequence of Sequences | Required | 按行组织或按列组织的数据矩阵。也可以稍后通过 `InsertContext` 提供。 |
| `column_names` | str or Sequence\[str] | `"*"` | 按顺序排列的列。`"*"` 会执行一次元数据查询，以发现所有可插入的列。 |
| `database` | str or None | Client database | 当 `table` 未限定数据库时使用的目标数据库。 |
| `column_types` | Sequence\[`ClickHouseType`] | `None` | 显式指定的列类型。提供后可避免执行元数据查询。 |
| `column_type_names` | Sequence\[str] | `None` | 显式指定的 ClickHouse 类型名称。可替代 `column_types`。 |
| `column_oriented` | bool | `False` | 将 `data` 解释为列而不是行。 |
| `settings` | dict | `None` | 参见 [Settings argument](#settings-argument-1)。 |
| `context` | `InsertContext` | `None` | 可复用的插入上下文。参见 [InsertContexts](/zh/integrations/language-clients/python/advanced-inserting#insertcontexts)。 |
| `transport_settings` | dict | `None` | 添加到此请求的 HTTP 请求头。 |

此方法返回 `QuerySummary`。其 `summary` 字典包含服务器报告的值。`written_rows` 是一个便捷属性，而 `written_bytes()` 和 `query_id()` 会返回对应的值。插入失败时会引发异常。

如需使用适用于 Pandas DataFrames、PyArrow Tables 和 Arrow-backed DataFrames 的专用插入方法，请参见 [高级插入 (专用插入方法) ](/zh/integrations/language-clients/python/advanced-inserting#specialized-insert-methods)。

<Note>
  NumPy 数组属于合法的 Sequence of Sequences，因此可直接作为主 `insert` 方法的 `data` 参数使用，无需专用方法。
</Note>

<h3 id="examples">
  示例
</h3>

以下示例假设已存在一张 `users` 表，其 schema 为 `(id UInt32, name String, age UInt8)`。

<h4 id="basic-row-oriented-insert">
  简单的按行插入
</h4>

```python theme={null}
import clickhouse_connect

client = clickhouse_connect.get_client()

# Row-oriented data: each inner list is a row
data = [
    [13, "user_1", 25],
    [79, "user_2", 30],
]

client.insert("users", data, column_names=["id", "name", "age"])
```

<h4 id="column-oriented-insert">
  按列插入
</h4>

```python theme={null}
import clickhouse_connect

client = clickhouse_connect.get_client()

# Column-oriented data: each inner list is a column
data = [
    [13, 79],  # id column
    ["user_1", "user_2"],  # name column
    [25, 30],  # age column
]

client.insert("users", data, column_names=["id", "name", "age"], column_oriented=True)
```

<h4 id="insert-with-explicit-column-types">
  使用显式指定的列类型进行插入
</h4>

```python theme={null}
import clickhouse_connect

client = clickhouse_connect.get_client()

# Useful when you want to avoid a DESCRIBE query to the server
data = [
    [13, "user_1", 25],
    [79, "user_2", 30],
]

client.insert(
    "users",
    data,
    column_names=["id", "name", "age"],
    column_type_names=["UInt32", "String", "UInt8"],
)
```

<h4 id="insert-into-specific-database">
  向特定数据库插入
</h4>

```python theme={null}
import clickhouse_connect

client = clickhouse_connect.get_client()

data = [
    [13, "user_1", 25],
    [79, "user_2", 30],
]

# Insert into a table in a specific database
client.insert(
    "users",
    data,
    column_names=["id", "name", "age"],
    database="production",
)
```

<h2 id="file-inserts">
  文件插入
</h2>

如需将数据直接从文件插入 ClickHouse 表，请参阅 [高级插入 (文件插入) ](/zh/integrations/language-clients/python/advanced-inserting#file-inserts)。

<h2 id="raw-api">
  原始 API
</h2>

对于需要直接访问 ClickHouse HTTP 接口且不进行类型转换的高级用例，请参阅[高级用法 (原始 API) ](/zh/integrations/language-clients/python/advanced-usage#raw-api)。

<h2 id="python-db-api-20">
  Python DB-API 2.0
</h2>

`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` 的一种。

```python theme={null}
from clickhouse_connect import dbapi

connection = dbapi.connect(
    host="localhost",
    username="default",
    password="password",
    database="default",
)
cursor = connection.cursor()

try:
    cursor.execute(
        "SELECT name FROM system.tables "
        "WHERE database = %(database)s ORDER BY name LIMIT 5",
        {"database": "system"},
    )
    print(cursor.description)
    print(cursor.fetchall())
finally:
    cursor.close()
    connection.close()
```

`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 并发规则](/zh/integrations/language-clients/python/advanced-usage#managing-clickhouse-session-ids)仍然适用。

<h2 id="utility-classes-and-functions">
  实用类和函数
</h2>

以下模块提供客户端应用程序可用的其他公开辅助工具。

已安装的软件包版本会以字符串 `clickhouse_connect.__version__` 的形式公开。

<h3 id="exceptions">
  异常
</h3>

自定义异常 (包括由 `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 错误文本。

<h3 id="clickhouse-sql-utilities">
  ClickHouse SQL 实用工具
</h3>

`clickhouse_connect.driver.binding` 模块中的函数和 DT64Param 类可用于正确构造并转义 ClickHouse SQL 查询。类似地，`clickhouse_connect.driver.parser` 模块中的函数可用于解析 ClickHouse 数据类型名称。

<h2 id="multithreaded-multiprocess-and-asyncevent-driven-use-cases">
  多线程、多进程和异步/事件驱动使用场景
</h2>

有关在多线程、多进程和异步/事件驱动应用中使用 ClickHouse Connect 的信息，请参阅[高级用法 (多线程、多进程和异步/事件驱动使用场景) ](/zh/integrations/language-clients/python/advanced-usage#multithreaded-multiprocess-and-asyncevent-driven-use-cases)。

<h2 id="asyncclient">
  AsyncClient
</h2>

有关原生 asyncio 用法，请参阅 [高级用法 (AsyncClient)](/zh/integrations/language-clients/python/advanced-usage#asyncclient)。

<h2 id="managing-clickhouse-session-ids">
  管理 ClickHouse 会话 ID
</h2>

有关如何在多线程或并发应用中管理 ClickHouse 会话 ID，请参阅[高级用法 (管理 ClickHouse 会话 ID) ](/zh/integrations/language-clients/python/advanced-usage#managing-clickhouse-session-ids)。

<h2 id="customizing-the-http-connection-pool">
  自定义 HTTP 连接池
</h2>

如需了解如何为大型多线程应用程序自定义 HTTP 连接池，请参阅[高级用法 (自定义 HTTP 连接池) ](/zh/integrations/language-clients/python/advanced-usage#customizing-the-http-connection-pool)。
