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

📺 Watch video tutorials → Olap Studio YouTube

Subscribe for more DuckDB & AI automation tutorials

使用 Hugo 构建
主题 StackJimmy 设计

⚠️ 本站为独立社区项目,与 DuckDB 基金会及 DuckDB 官方项目无任何从属、背书或赞助关系。

"DuckDB" 是 DuckDB 基金会的注册商标,本站仅以事实描述方式使用该名称。

本站内容仅供教育与社区推广用途,不构成任何商业服务。