商品导入一次读 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 左右,进程正常退出,导入条数与原文件一致。

作者 9823189