duckdb_orc 0.2.0:DuckDB 能写 ORC 了
DuckDB 至今不支持 ORC。2023 年有人在官方讨论区问过,维护者 hannes 的回答很直接:"No plans, ORC seems far less popular than Parquet"。直到现在,官方扩展列表里也没有 orc。
但 ORC 没死。Hive 的老用户在用,Trino 生态的主力格式也是它。国内很多数仓历史数据就是一堆 .orc 文件,想用 DuckDB 分析,只能先转格式。
我给 DuckDB 写的 ORC 扩展 duckdb_orc,0.1.x 时代只能读。今天 0.2.0 发布,补齐了写:一条 COPY 就能把任意查询结果写成 ORC 文件。
duckdb_orc 读写流程
● ● ●
0.2.0 新增了什么
核心就一件事:写支持。
-- 读 ORC(0.1.x 就有)
SELECT * FROM read_orc('sales.orc');
-- 写 ORC(0.2.0 新增)
COPY sales TO 'sales_copy.orc' (FORMAT orc);
-- 任意查询结果都可以写
COPY (SELECT region, SUM(amount) AS total FROM sales GROUP BY region)
TO 'region_total.orc' (FORMAT orc);
写入默认 ZSTD 压缩,2048 行一批流式写,文件多大都不占内存。整个扩展纯 Rust,基于 orc-rust 的 ArrowWriter。
● ● ●
实测验证
发布前我把读写都跑了一遍(DuckDB 1.5.5 + 本地构建的扩展):
读(内置 1 万行测试文件):
写 + 回读(100 行混合类型:int、varchar、double、bool、date、timestamp):
不支持的类型:LIST 写入时给干净的 Binder Error,不会崩进程:
Binder Error: write_orc: type List(Field { data_type: Int32, nullable: true })
not supported by the ORC writer yet (supported: bool, int8-64, float32/64,
date, timestamp, varchar, blob)
● ● ●
已知边界
- 写类型白名单
:bool、int8/16/32/64、float32/64、date、timestamp、varchar、blob。list/struct/map/decimal 会被干净拒绝——上游 orc-rust 的 writer 还没实现这些编码 - 列名是 column_N
:DuckDB C API 的 COPY bind 不暴露源列名,所以写出来的 ORC 列名是 column_0、column_1……读回时注意按位置取列 - 没有 filter pushdown
:DuckDB C 扩展 API 没暴露这个接口,过滤在扫描后应用(投影下推是有的) - 写性能
:ZSTD 压缩是默认且目前可切换的(改源码里的压缩配置)
● ● ●
怎么装
INSTALL orc FROM community;
LOAD orc;
社区注册表已经合并(duckdb/community-extensions#2589),全平台二进制由 CI 自动构建发布。源码在 github.com/alitrack/duckdb_orc,MIT 协议。
说实话,ORC 在国内数据栈里的存量比 GitHub 讨论区看起来大得多——Hive 时代留下的 .orc 仓库,很多公司到现在还在用 Trino 或 Spark 读。这也是我做这个扩展的原因。DuckDB 官方说 No plans 的格式,我用一个 10.7MB 的扩展补上了读写。ORC 文件在 DuckDB 里,不用先转格式了。
如果你也被 ORC 历史数据卡过:装了扩展后,COPY 一条语句转 Parquet 再分析,还是直接 read_orc 查,哪种更顺手?评论区聊聊。
参考来源
- 01
DuckDB 官方对 ORC 的表态(维护者 hannes:No plans)https://github.com/duckdb/duckdb/discussions/6529 - 02
DuckDB 社区扩展注册表 orc 条目(合并 PR #2589) https://github.com/duckdb/community-extensions/pull/2589 - 03
duckdb_orc 源码仓库 https://github.com/alitrack/duckdb_orc - 04
上游 orc-rust(Arrow 读写) https://github.com/datafusion-contrib/orc-rust - 05
实测数据来源:DuckDB 1.5.5 + 本地构建的 v0.2.0 扩展(read/write/roundtrip 验证脚本)