DuckDB 实战笔记 - 2026-08-22
🦆 DuckDB 实战笔记 | 2026-08-22(周六)
进阶技巧:Parquet 文件读写出错?99% 是这个问题
场景: 你的 ETL 管道每天产出 Parquet 文件,但 DuckDB 读起来报错:Invalid Input Error: Expected schema to have consistent columns。排查半天,发现是上游不同批次产出的 Parquet 文件列顺序不一致。
问题根源: Parquet 是列式存储格式,不同工具写出的 Parquet 文件列顺序可能不同。DuckDB 默认按列名匹配,但如果文件内部 schema 不一致,就会报 schema 错误。
解决方案一:强制统一 schema(推荐)
import duckdb
# 读取 Parquet,自动对齐列(缺失列补 NULL)
df = duckdb.sql("""
SELECT * FROM read_parquet('data/*.parquet',
hive_partitioning=true,
union_by_name=true)
""").df()
# 或者显式指定需要的列
df = duckdb.sql("""
SELECT date, user_id, amount, category
FROM read_parquet('data/*.parquet', union_by_name=true)
""").df()
解决方案二:用 schema 约束统一写入
import pyarrow as pa
import pyarrow.parquet as pq
# 定义统一 schema
schema = pa.schema([
('date', 'date32'),
('user_id', 'int64'),
('amount', 'float64'),
('category', 'string')
])
# 写入时强制用同一 schema
table = pa.table({
'date': [pa.scalar('2026-08-22', type='date32')],
'user_id': [12345],
'amount': [99.9],
'category': ['electronics']
}, schema=schema)
pq.write_table(table, 'output.parquet')
为什么用 DuckDB 处理 Parquet 更顺手?
- 零 schema 声明:
read_parquet()自动推断 schema,比 Pandas 少写一半代码 - 列式查询优化:只读需要的列,10GB 文件读 3 列不到 1 秒
- 原生 Parquet 支持:直接查 S3/GCS 上的 Parquet,不用下载
- 与 Arrow 无缝集成:DuckDB DataFrame 可以直接转 PyArrow Table
进阶技巧:查看 Parquet 内部 schema
-- 不用读数据,只看 schema 结构
DESCRIBE SELECT * FROM read_parquet('data/file.parquet');
-- 查看所有 Parquet 文件的 schema 差异
SELECT file_name, column_name, column_type
FROM parquet_schema('data/*.parquet')
ORDER BY file_name, ordinal_position;
坑提醒: 如果 Parquet 文件是用 fastparquet 库写出的,列名可能带 .0 后缀。用 duckdb.read_parquet(‘file.parquet’, promote_types=True) 可以自动处理。
👆 遇到 Parquet schema 错误,先用 parquet_schema() 查看差异,再用 union_by_name 对齐。
#DuckDB #Parquet #数据工程 #ETL