使用 ClickHouse Connect 插入数据:高级用法
InsertContexts
InsertContext 中执行。InsertContext 包含传递给客户端 insert 方法的所有参数值。此外,在初次构造 InsertContext 时,ClickHouse Connect 还会获取插入列的数据类型,以便高效地进行 Native format 插入。复用同一个 InsertContext 执行多次插入时,就可以避免这类“预查询”,从而让插入更快、更高效。
可以使用客户端的 create_insert_context 方法获取 InsertContext。该方法接受的参数与 insert 函数相同。请注意,复用 InsertContext 时,只应修改其 data 属性。这也符合它的设计目的:为向同一张表重复插入新数据提供一个可复用的对象。
InsertContexts 包含会在 insert 过程中更新的可变状态,因此不具备线程安全性。
写入格式
DateTime 列插入数据,而该列的第一个插入值是 Python 整数,ClickHouse Connect 会直接插入该整数值,并假定它实际上表示纪元秒。
大多数情况下,无需覆盖某种数据类型的写入格式;但如果需要,也可以使用 clickhouse_connect.datatypes.format 包中的相关方法在全局级别进行设置。
写入格式选项
专用插入方法
insert_df— 插入 Pandas DataFrame。此方法的第二个参数需要传入df参数,且该参数必须是 Pandas DataFrame 实例,而不是 Python 的 Sequence of Sequences 类型data参数。ClickHouse Connect 会自动将 DataFrame 作为列式数据源处理,因此不需要column_oriented参数,也不提供该参数。insert_arrow— 插入 PyArrow Table。ClickHouse Connect 会将 Arrow 表原样传递给 ClickHouse server 处理,因此除了table和arrow_table之外,只有database和settings参数可用。insert_df_arrow— 插入基于 Arrow 的 Pandas DataFrame 或 Polars DataFrame。ClickHouse Connect 会自动判断该 DataFrame 是 Pandas 类型还是 Polars 类型。如果是 Pandas,则会进行校验,以确保每一列的 dtype backend 都基于 Arrow;如果有任意一列不满足条件,则会引发错误。
NumPy array 是合法的 Sequence of Sequences,因此可作为主
insert 方法的 data 参数使用,无需专用方法。插入 Pandas DataFrame
PyArrow Table 插入操作
基于 Arrow 的 DataFrame 插入 (pandas 2.x)
时区
datetime.datetime 对象插入 ClickHouse 的 DateTime 或 DateTime64 列时,ClickHouse Connect 会自动处理时区信息。由于 ClickHouse 在内部将所有 DateTime 值存储为不带时区信息的 Unix 时间戳 (即自纪元以来的秒或小数秒) ,因此插入时的时区转换会由客户端自动完成。
带时区信息的 datetime 对象
datetime.datetime 对象,ClickHouse Connect 会自动调用 .timestamp() 将其转换为 Unix 时间戳,从而正确处理时区偏移。这意味着你可以插入来自任何时区的 datetime 对象,并且它们都会以对应的 UTC 时间戳被正确存储。
使用 pytz 时,必须使用
localize() 方法为 naive datetime 添加时区信息。直接将 tzinfo= 传给 datetime 构造函数会使用错误的历史偏移量。对于 UTC,tzinfo=pytz.UTC 可以正常工作。更多信息请参见 pytz 文档。不含时区信息的 datetime 对象
datetime.datetime 对象 (即没有 tzinfo 的对象) ,.timestamp() 方法会将其视为系统本地时区的时间。为避免歧义,建议:
- 插入时始终使用带时区信息的 datetime 对象,或
- 确保系统时区设置为 UTC,或
- 在插入前手动转换为纪元时间戳
带有时区元数据的 DateTime 列
DateTime('America/Denver') 或 DateTime64(3, 'Asia/Tokyo')) 。这些元数据不会影响数据的存储方式 (仍以 UTC 时间戳存储) ,但会决定从 ClickHouse 查询数据时使用的时区。
向此类列插入数据时,ClickHouse Connect 会将你的 Python datetime 转换为 Unix timestamp (如果包含时区信息,也会一并考虑) 。查询数据时,无论插入时使用的是哪个时区,ClickHouse Connect 返回的 datetime 都会转换为该列的时区。
文件插入
clickhouse_connect.driver.tools 包提供了 insert_file 方法,可将数据直接从文件系统插入现有的 ClickHouse 表中。解析工作由 ClickHouse server 负责。insert_file 接受以下参数:
对于数据不一致或日期/时间值格式不常见的文件,此方法也支持适用于数据导入的 settings (例如
input_format_allow_errors_num 和 input_format_allow_errors_num) 。