先把当时的情况摆出来。批量写入时部分记录报 Expected metadata to be a non-empty dict,把 metadata 去掉后又能正常写入。

把日志和配置对完,能解释这个现象的基本就这几处。metadata 传了空字典,接口不接受空值。另一种情况是字段值里有 None,被判定为非法类型。

还有一种情况,嵌套结构不被支持,只能存基础类型。另外,同一个集合里 metadata 结构前后不一致。

第一件事是把空字典改成 None 或补一个字段

metas = [m if m else None for m in metas]

过滤掉值为 None 的键

m = {k: v for k, v in m.items() if v is not None}

接着确认值的类型在支持范围内

python -c "print({k: type(v).__name__ for k,v in m.items()})"

剩下的就是分批写入并记录失败样本

python ingest.py --batch 200 --log failed.jsonl

改之前我把相关日志按时间截了一段存着,事后对时间线用得上。

别只看报错消失,验证要多做一步。全部记录写入成功,count 与输入条数一致,按 metadata 过滤也能查到目标片段。

容易忽略的是,元数据只支持字符串、数字和布尔值,把列表塞进去会直接报错,需要存多值时先转成逗号分隔的字符串。线上能稳定复现的问题都不算难,难的是只在大流量下才出现的那种。

作者 9823189