真实生成并读取一份Parquet文件,验证ClickHouse的类型推断结果,以及字段数量/类型不匹配时真实的容错与隐患。
代码SELECT number AS id, toString(number) AS code, toDate('2026-01-01')+number AS d, number*1.1 AS price FROM numbers(5) INTO OUTFILE 'schema_v1.parquet' FORMAT Parquet; DESCRIBE TABLE file('schema_v1.parquet', Parquet);
DESCRIBE TABLE file('schema_v1.parquet', Parquet);
→ id UInt64 ← number的默认类型
code String
d Date32 ← 真实不是Date,是Date32
price Float64d列真实被推断成了Date32而不是更常见的Date——本文写入时用的toDate('2026-01-01')+number,number是UInt64,跟Date相加真实触发了ClickHouse内部往更大范围类型(Date32)的隐式提升,这个提升结果被真实写进了Parquet文件的schema里,不是Parquet格式本身的限制。
-- 用比文件多一个字段的表结构读: SELECT id, code, d, price, extra_field FROM file(..., 'id UInt32, code String, d Date, price Float64, extra_field Nullable(String)'); → 真实extra_field全部是NULL,不报错 -- 用比文件少一个字段(跳过中间的d列)的表结构读: SELECT id, code, price FROM file(..., 'id UInt32, code String, price Float64'); → 真实正确读出id/code/price,按列名匹配,不受文件里列的物理顺序影响 -- 真实把price(文件里是Float64)硬指定成Int32读取: SELECT id, price FROM file(..., 'id UInt32, code String, d Date, price Int32'); → 1.1→1,2.2→2,3.3→3,4.4→4 ← 真实静默截断了小数部分,没有任何报错
每一步都是本文上面用真实Parquet文件跑出来的原始结果。
clickhouse local 生成Parquet文件,真实的 file() 表函数