不能直接用 pyarrow.parquet.write_table() 循环追加,因为该函数每次调用都会覆盖原文件而非追加,且不支持 append=True 参数;正确做法是分批写入目录并用 write_dataset() 自动管理分片。

为什么不能直接用 pyarrow.parquet.write_table() 循环追加?
Parquet 是列式存储格式,本身不支持“在文件末尾追加数据”——它没有类似 CSV 的流式追加语义。每次调用 pyarrow.parquet.write_table() 并指定同一文件路径,都会**覆盖原文件**,不是追加。你看到数据“变多了”,大概率是误以为写入了多次,实际只是最后一次写入生效。
常见错误现象:
– 循环中反复写同一个 output.parquet,最终只保留最后一块数据
– 用 append=True 参数(该参数在 write_table() 中根本不存在,会报 TypeError: write_table() got an unexpected keyword argument 'append')
正确做法:分批写入 + 合并(推荐 pyarrow.dataset.write_dataset())
最实用、可控性最强的方式是:把每批数据构造成独立的 pyarrow.Table,统一交给 pyarrow.dataset.write_dataset() 写入一个目录,由它自动管理分片(如 part-0.parquet, part-1.parquet 等),后续读取时可透明合并。
实操建议:
立即学习“Python免费学习笔记(深入)”;
- 不要写单个文件,改用目录路径作为输出目标(例如
"data/output_dataset"而非"data/output.parquet") - 设置
format="parquet"和partitioning=None(避免意外分区) - 用
existing_data_behavior="overwrite_or_ignore"控制重跑逻辑(慎用"delete_matching",易误删) - 若需压缩,显式传
file_options=pa.dataset.ParquetFileFormat().make_write_options(compression="snappy")
示例片段:
让 macOS 自动化像说话一样简单 —— 用代码控制你的 Mac,无需学习 AppleScript 系统要求 macOS 14+ (Sonoma) Python 3.9+ 需要开启:辅助功能 + 屏幕录制权限
import pyarrow as pa import pyarrow.dataset as ds <h1>假设 batch_table 是某次处理得到的 pa.Table</h1><p>ds.write_dataset( batch_table, base_dir="data/output_dataset", format="parquet", file_options=pa.dataset.ParquetFileFormat().make_write_options(compression="zstd"), existing_data_behavior="overwrite_or_ignore" )
如果硬要单文件,只能先读再拼再写(仅限小规模)
所谓“追加到单个 Parquet 文件”,本质是:读取已有文件 → 合并新数据 → 全量重写。这在数据量大时非常危险:内存占用翻倍(旧数据 + 新数据),I/O 成倍增加,且无法中断恢复。
适用场景仅限:总数据量
关键点:
- 必须用
pa.parquet.read_table()读原文件,不能用 pandas(类型推断可能出错) - 两表 schema 必须完全一致,否则
pa.concat_tables()报ArrowInvalid - 写回时务必用
use_dictionary=False, compression="snappy"控制体积和性能 - 不要省略
use_threads=True,否则单线程写大文件极慢
简例:
old = pa.parquet.read_table("data/output.parquet")
combined = pa.concat_tables([old, new_batch])
pa.parquet.write_table(combined, "data/output.parquet", use_threads=True, compression="snappy")写入性能关键参数与避坑点
无论用 dataset 还是全量重写,以下参数直接影响吞吐和稳定性:
-
max_row_group_size(dataset 场景):设为 50_000–200_000 行较稳;太小导致文件碎片多,太大影响查询粒度 -
use_dictionary=True默认开启,但字符串列重复率低时反而膨胀体积,可关掉 - 避免在循环内反复创建
pa.Schema或调用pa.table()构造函数——提前定义 schema,用pa.RecordBatch.from_arrays()批量构造更高效 - 磁盘空间要预留至少 2× 当前数据量:dataset 写入过程会先写临时文件,再原子替换
真正容易被忽略的是 schema 一致性。不同批次若字段顺序、nullability、字典编码状态不一致,concat_tables() 或 dataset 合并会静默失败或读取出错——建议每次写入前 assert table.schema == expected_schema。

















