polars 0.20 用 scan_parquet 读按天分区的目录,今天新增文件里 order_id 从 int64 变成 string,collect 时抛 SchemaError: data type mismatch for column order_id,单读旧文件正常,给 scan 指定 schema 后报错换到另一列。

一开始怀疑是「上游把空值写成了字符串 null」,查了一圈,方向不对。

把日志和配置对完,能解释这个现象的基本就这几处。新旧文件同名列的数据类型不同。还有一种是分区目录里混进了 _SUCCESS 空文件。

还有一种情况,列顺序变化被当成不同 schema。

动手时先逐文件打印 schema 找出差异

python -c "import polars as pl,glob;[print(f,pl.read_parquet_schema(f)) for f in glob.glob('data/*.parquet')]"

scan 时显式 cast 成统一类型

python -c "import polars as pl;print(pl.scan_parquet('data/*.parquet').with_columns(pl.col('order_id').cast(pl.Utf8)).collect().shape)"

然后用放宽模式合并多份数据

python -c "import polars as pl;print(pl.concat([pl.read_parquet(f) for f in ['a.parquet','b.parquet']],how='diagonal_relaxed').shape)"

等前面都确认过,再写入端固定 schema 并加一次校验

python writer.py --schema schema.json --validate true

这类改动我都写进变更记录,过两周再出问题时能对上号。

恢复的判定其实很直接。collect 成功且 order_id 全部为字符串,行数等于各分区之和,没有空文件导致的额外行。

补一句。scan 是惰性的,类型错误往往在 collect 或 sink 时才抛出,别在 scan 那一行找原因。监控比日志更早给出信号,事后回看经常能提前半小时发现异常。

作者 9823189