说明
数据类型匹配
写入 Parquet 文件时,没有对应 Parquet 类型的数据类型会被转换为最接近的可用类型:
Array 可以嵌套,其参数值也可以是
Nullable 类型。Tuple 和 Map 类型同样可以嵌套。
ClickHouse 表列的数据类型可以与插入的 Parquet 数据中对应字段的类型不同。插入数据时,ClickHouse 会先根据上表解释数据类型,然后将数据 转换 为 ClickHouse 表列所设置的数据类型。例如,UINT_32 Parquet 列可以读入 IPv4 ClickHouse 列中。
对于某些 Parquet 类型,并没有与之非常接近的 ClickHouse 类型。我们按如下方式读取它们:
TIME(一天中的时间) 会被读取为时间戳。例如,10:23:13.000会变成1970-01-01 10:23:13.000。- 设置了
isAdjustedToUTC=false的TIMESTAMP/TIME表示本地挂钟时间 (即本地时区中的年、月、日、时、分、秒和亚秒字段,不论具体将哪个 timezone 视为本地) ,与 SQLTIMESTAMP WITHOUT TIME ZONE相同。但 ClickHouse 读取时会改为将其视作 UTC 时间戳。例如,2025-09-29 18:42:13.000(表示本地挂钟上的读数) 会变成2025-09-29 18:42:13.000(DateTime64(3, 'UTC'),表示一个时间点) 。如果将其转换为 String,会显示正确的年、月、日、时、分、秒和亚秒,此时可以将其理解为某个本地时区中的时间,而不是 UTC。违反直觉的是,把类型从DateTime64(3, 'UTC')改为DateTime64(3)也没有帮助,因为这两种类型表示的都是时间点,而不是时钟读数;但DateTime64(3)还会错误地使用本地时区进行格式化。 INTERVAL当前会被读取为FixedString(12),内容是时间间隔的原始二进制表示,编码方式与 Parquet 文件中一致。
Geo 类型 (GeoParquet)
BYTE_ARRAY 载荷形式存储 (读取时也支持 WKT) ,并在文件级 Parquet 元数据中通过一个 JSON geo 键描述每个几何列的编码、几何类型和 CRS。
读取行为
- 声明为
Point、LineString、Polygon、MultiLineString或MultiPolygon的列,会读取为对应的 ClickHouse geo type。 - 包含多种或未知几何类型的列,会读取为
Geometry类型,它是一个涵盖所有受支持 geo types 的Variant。 - 如果请求的列类型为
String,则会忽略 GeoParquet 元数据,并按原样返回原始编码的几何载荷——WKB 或 WKT 字节,具体取决于 GeoParquet 列声明的编码类型。如果设置input_format_parquet_allow_geoparquet_parser为0,也是如此。
写入行为
Point、LineString、Polygon、MultiLineString 或 MultiPolygon 的顶层列会编码为 BYTE_ARRAY (WKB) ,并将相应的 geo JSON 元数据 追加到 Parquet 文件页脚。顶层的 Geometry Variant 也会被编码为 WKB BYTE_ARRAY 载荷 (其子值会转换为 WKB,并存储为 Nullable(String) 列) ,但不会为其输出 geo 元数据,因此读取时,结果不会被识别为 GeoParquet 几何列。其他与 geo 相关的类型 (例如 Ring) 则会使用其原生底层表示写入,不附带任何 GeoParquet 元数据。将 output_format_parquet_geometadata 设置为 0 可完全禁用此行为;在这种情况下,即使是受支持的 geo 类型,也会使用其原生底层表示写入 (Point 写为 Tuple(Float64, Float64),LineString 写为 Array(Point),Polygon 写为 Array(Array(Point)),等等) ,并且不会输出任何 GeoParquet 元数据。
几何列必须位于 schema 根级,或嵌套在 Tuple (struct) 内;不支持将其嵌套在 Array 或 Map 中。geo 列同样也不支持 Nullable。
使用示例
插入数据
football.parquet 的 Parquet 文件,内容如下:
读取数据
Parquet 格式读取数据:
HDFS 表引擎。