先把当时的情况摆出来。从 PDF 发票里抽金额,模型返回的是带千分位的文本 12,480.00,直接塞进 numeric 字段,Postgres 报 22P02 invalid input syntax for type numeric,批量入库失败一千多条,原样重跑还是同样的错。

真正麻烦的地方在于,几个原因的现象几乎一样。文本里的千分位逗号没有去掉就入库。也可能是字段里混着货币符号和全角数字。

还有一种情况,模型返回的金额有时是数字有时是字符串。另外,负数用括号写法,直接转 float 会失败。

先把失败样本的原文打出来看格式

python -c "import json;print([json.loads(l)['amount'] for l in open('fail.jsonl',encoding='utf-8')][:5])"

去掉千分位与货币符号再转数值

python -c "import re;v='¥12,480.00';print(float(re.sub(r'[^0-9.\-]','',v)))"

入库改成参数化语句按 numeric 传值

psql -c "INSERT INTO invoice(order_no,amount) VALUES ('A-8842', 12480.00);"

全量重跑并核对金额合计

python load_invoice.py --in fail.jsonl --retry --sum-check

怎么算真的好了,看的是同一批现象。重跑后一千多条全部入库,金额合计与发票汇总差零元,库里该字段类型是 numeric 而不是 text。

补一句。金额在文本和数值之间来回转最容易出错,清洗规则要覆盖千分位、货币符号和括号负数三种写法。拖得越久,排查成本越高,因为现场状态会被后续操作覆盖。

作者 9823189