商品导入一次读 20 万行 Excel,进程 RSS 从 400M 涨到 3.2G,十分钟后被系统 OOM Killer 杀掉,容器退出码 137,日志里没有任何 Python 异常。第一次遇到会往复杂处想,其实漏掉的多是个小前提。
from openpyxl import load_workbook
wb = load_workbook(path, read_only=True)
for i, row in enumerate(wb.active.iter_rows(values_only=True), 1):
if i % 1000 == 0:
session.commit()
整本工作簿被一次性解析成 list[dict],每行一个字典加十几个字符串对象,内存开销是原文件的十倍以上。分批写库以后外层列表还持有全部行,垃圾回收没有机会释放。这一点先确认清楚,后面就不用反复试。
「导入内存溢出」这个问题文档写得含糊,实际行为以当前版本为准,别照旧版本的结论套。把这次用到的命令存进笔记,比记住结论有用,换个环境还能照着走。
改完隔一天再看一次,当场正常不代表能稳住。
具体做法是,改成 read_only 模式逐行读 不要先 list 化;每 1000 行提交一次事务 同时把这一批的引用清掉;给容器设内存上限并观察 RSS 曲线 确认峰值不再随行数线性上涨。
改完照着核一遍,同一份 20 万行文件重跑,RSS 峰值稳定在 700M 左右,进程正常退出,导入条数与原文件一致。
