You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

ClickHouse结合SQLAlchemy查询结果丢失两行问题排查

问题分析与解决方案

这事儿我之前碰到过类似的,结合你给出的版本信息(SQLAlchemy 1.3.11、ClickHouse 19.17.4.11),咱们来拆解下问题根源和解决办法:

核心原因

ClickHouse的Date类型底层是UInt16,有效日期范围是1970-01-01 到 2105-12-31(对应天数0到65535)。你插入的created值(11345678、13345678这类大数字)远远超出了这个范围,插入时会触发数值溢出,生成的日期超出了旧版本SQLAlchemy ClickHouse驱动的解析能力。旧驱动碰到这类无法解析的日期时,会直接丢弃对应行,导致你只拿到2条结果。

验证步骤

你可以在clickhouse-client里执行这条命令,看看实际存储的日期和对应的数值:

SELECT id, created, toUInt16(created) AS created_uint FROM test_table;

会发现超出范围的created值已经溢出,生成的日期(比如2086年及以后)是旧驱动处理不了的。

解决方案

方案1:修正Date类型的取值范围

确保插入的created值在ClickHouse Date类型的有效范围内(天数0到65535,对应1970-01-01至2105-12-31)。比如把原始数值转换为合法日期后再插入:

INSERT INTO test_table (id, created) VALUES (1, toDate('1991-09-08'));

方案2:升级依赖版本

旧版本的SQLAlchemy和ClickHouse驱动存在日期解析bug,升级到较新版本就能解决:

  • 把SQLAlchemy升级到2.x稳定版
  • 升级clickhouse-driver(SQLAlchemy ClickHouse适配器依赖的驱动)到最新版
    升级后重新运行Python脚本,应该就能拿到全部4行数据了。

方案3:修改字段类型

如果业务确实需要存储超出Date范围的日期,可以把created字段类型改成DateTime64或者String,避免数值溢出问题:

-- 已有表修改字段
ALTER TABLE test_table MODIFY COLUMN created DateTime64;

-- 新建表时直接指定
CREATE TABLE test_table (id INTEGER, created DateTime64) ENGINE = MergeTree(created, (id), 8192);

内容的提问来源于stack exchange,提问作者sanyassh

火山引擎 最新活动