Skip to main content

使用 ClickHouse Connect 插入数据:高级用法

InsertContexts

ClickHouse Connect 的 Native-format 插入操作,以及 insertinsert_df 方法,都在 InsertContext 中执行。insert_arrowinsert_df_arrowraw_insert 方法会直接发送其载荷,而不会使用 InsertContextInsertContext 包含传递给客户端 insert 方法的所有参数值。此外,在初次构造 InsertContext 时,ClickHouse Connect 还会获取插入列的数据类型,以便高效地进行 Native format 插入。复用同一个 InsertContext 执行多次插入时,就可以避免这类“预查询”,从而让插入更快、更高效。 可以使用客户端的 create_insert_context 方法获取 InsertContext。该方法接受的参数与 insert 函数相同,但 context 本身除外。请注意,复用 InsertContext 时,只应修改其 data 属性。这也符合它的设计目的:为向同一张表重复插入新数据提供一个可复用的对象。
InsertContexts 包含会在 insert 过程中更新的可变状态,因此不具备线程安全性。

写入格式

只有少数类型实现了写入格式。在大多数情况下,ClickHouse Connect 会根据列中第一个非 NULL 的数据值自动判断正确的写入格式。例如,当 DateTime 列的第一个值是整数时,client 会将其视为纪元秒。 通常无需覆盖写入格式,但 clickhouse_connect.datatypes.format 中的方法可以在全局范围内进行设置。像 ArrayNullableLowCardinality 这样的容器包装器会保留其元素类型的格式行为。

写入格式选项

专用插入方法

ClickHouse Connect 为常见数据格式提供了专用的插入方法:
  • insert_df — 将 Pandas DataFrame 作为列式 Native 数据插入。它还支持显式指定列名/类型,或使用可复用的 InsertContext
  • insert_arrow — 使用 ClickHouse Arrow 输入格式插入 PyArrow Table。
  • insert_df_arrow — 插入基于 Arrow 的 Pandas DataFrame 或 Polars DataFrame。Pandas 的所有列都必须使用基于 Arrow 的 dtype。
这三种方法都接受 databasesettings 和按请求指定的 HTTP transport_settings
NumPy array 是合法的 Sequence of Sequences,因此可作为主 insert 方法的 data 参数使用,无需专用方法。

插入 Pandas DataFrame

PyArrow Table 插入操作

基于 Arrow 的 DataFrame 插入 (pandas 2.x)

根据 PyArrow schema 创建表

create_table_from_arrow_schema 会根据常见的标量 Arrow field 构建 CREATE TABLE 语句。该映射涵盖有符号和无符号整数、浮点值、布尔值、字符串、日期和时间戳。它会刻意创建不可为 NULL 的 ClickHouse 列,并在遇到不受支持的 Arrow type 时引发 TypeError,因此请在执行前先检查生成的 DDL。

时区

将 Python datetime 对象插入 DateTimeDateTime64 列时,ClickHouse Connect 会将其转换为自纪元开始计数的值。

带时区信息的 datetime 对象

带时区信息的对象会保留其所表示的时刻。源时区无需与 ClickHouse 列中声明的时区一致。
ClickHouse Connect 使用标准库中的 zoneinfo 模块。该驱动不再依赖 pytz

不带时区的 datetime 对象

全局 naive_datetime_insert 设置用于控制插入不带时区的原生 Python datetime 对象。它也适用于 DateTime64 列接受的不带时区的 ISO 字符串。
  • "local" 是 1.x 中的默认值。调用 .timestamp() 时,Python 会根据进程时区解释该值,从而保持现有行为。
  • "server" 会将该值解释为 DateTimeDateTime64 列所声明时区中的墙钟时间。如果该列未指定时区,则使用客户端连接时获取的服务器时区。
请在插入前设置该选项。序列化每个包含 Python datetime 对象或 DateTime64 ISO 字符串的原生插入列时,都会读取此选项,因此更改会应用于现有客户端和可复用的插入上下文。
使用 "server" 时,ClickHouse Connect 会先附加目标 tzinfo,再将值转换为纪元时间。对于 IANA 时区,它遵循标准库处理夏令时切换的规则。秋季重叠时段使用 datetime 的 fold 值。默认的 fold=0 选择切换前的偏移量,而 fold=1 选择切换后的偏移量。春季间隙采用相同的偏移量选择方式,不会被拒绝或归一化。 不存在的春季间隙墙钟时间可能无法通过墙钟模式查询参数往返转换,因为 ClickHouse 的文本解析可能会选择不同的偏移量。当具体时刻很重要时,请使用带时区信息的 datetime 或有效的墙钟时间。 该选项仅适用于原生 Python datetime 对象的插入,以及 DateTime64 接受的不带时区的 ISO 字符串。不带时区的 datetime64-dtype 的 NumPy 和 Pandas 列会保留其现有的 UTC 墙钟时间转换方式。 若要表示不依赖于任一模式的特定时刻,请附加预期的时区,或显式提供纪元整数。
不含时区信息的 datetime 查询参数使用独立的 naive_datetime_binding 设置。默认的 "wall" 模式会按原样发送日期时间字段,不进行主机本地时区转换。请参阅参数 argument部分。

带有时区元数据的 DateTime 列

ClickHouse 列可以声明时区元数据,例如 DateTime('America/Denver')DateTime64(3, 'Asia/Tokyo')。这些元数据决定了值在查询时的显示方式。 插入带时区信息的值时,ClickHouse Connect 会保留其所表示的时刻。对于不带时区信息的值,naive_datetime_insert 设置决定使用进程时区还是列时区。查询时,结果会使用该列的时区,除非通过 column_tzs 参数为特定列提供覆盖设置。query_tz 参数不会覆盖列中已声明的时区。

File 插入

clickhouse_connect.driver.tools.insert_file 会以流式方式将本地文件插入现有表中,并由 ClickHouse 负责解析。 可通过 settings 传递输入格式设置,例如 input_format_allow_errors_ratioinput_format_allow_errors_num
对于 AsyncClient,使用相同参数 await insert_file_async
async 辅助函数会先在工作线程中读取文件,再等待 raw_insert,因此文件内容会保存在内存中。
最后修改于 2026年8月14日