You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

访问Django模型时PDF库出现非确定性异常,如何定位原因?

问题排查:PDF处理偶发损坏与数据库访问的关联

基于Django 4.2和Python 3.10的应用,在本该无状态的处理环节偶发异常:当使用pypdf 3.17.4处理PDF时,如果同时通过psycopg 3.1.18访问PostgreSQL 14数据库,输出的PDF文档会损坏,大约每8次尝试就会出现1次。损坏的PDF存在内容缺失,因此可以通过对比输出文件大小来判断是否触发了问题。

复现代码

# 调用方式: python3 manage.py minrepro input.pdf
import argparse, io
from django.core.management.base import BaseCommand
from pypdf import PdfReader, PdfWriter
from djangoapp.models import DjangoModel


def main(fin):
    pdfout = PdfWriter()
    pageout = pdfout.add_blank_page(width=200, height=200)

    for i in range(8):
        # 注意:PDF合并过程中访问数据库是关键!
        # 注释掉下面这行就无法复现问题
        for c in range(31): a = DjangoModel.objects.first()

        fin.seek(0)
        for pagein in PdfReader(fin, strict=True).pages:
            pageout.merge_page(pagein)

    with io.BytesIO() as fout:
        pdfout.write(fout)
        return fout.tell()

class Command(BaseCommand):
    def add_arguments(self, parser):
        parser.add_argument(dest="pdf", type=argparse.FileType("rb") )
    def handle(self, *args, **options):
        for i in range(30):
            if i == 0: first_size = main(options["pdf"])
            current_size = main(options["pdf"])
            if not first_size == current_size:
                print(f"无状态调用出现异常 {i=}, {first_size=} != {current_size=}")

初步排查情况

  • 最初猜测pypdf未能为合并后的重复标识符生成真正唯一的名称,数据库访问只是让问题显现的触发条件,但在相关库中未找到time或random模块的导入,用time.sleep(0.02)替代数据库访问也无法复现问题,只有数据库访问能触发异常;
  • 使用的是支持插入顺序字典的CPython,相同输入下代码逻辑应完全一致,开启-W module::ResourceWarning等警告也未发现相关问题;
  • 已在单线程的Django管理命令中复现该问题,因此可以排除HTTP/Web服务器的影响。

内容的提问来源于stack exchange,提问作者user

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.27 12:04:53