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

Django导入CSV创建关联模型时触发TransactionManagementError怎么解决

错误根因
  • 你的代码运行在一个外层atomic事务块中,在执行POL的get_or_create之前,前面的逻辑(比如PO创建时的信号触发、关联product的查询逻辑、PO的JSONField字段约束校验)已经触发了未捕获的数据库异常,Django会将当前事务标记为需要回滚,此时任何后续的数据库操作都会抛出TransactionManagementError。
  • 额外的冗余操作也可能放大问题:你通过po.purchaseorderline_set调用get_or_create时,重复传入了purchase_order=po筛选参数,同时get_or_create返回的实例已经持久化到数据库,你额外调用的pol.save()属于冗余操作,若POL模型有自定义逻辑可能重复触发异常。
修复步骤
  • 第一步:给每行的处理逻辑增加独立事务和异常捕获,定位具体报错点,同时避免单条数据异常导致整个导入任务失败,修改后的参考代码如下:
@classmethod
def parse_purchase_order_from_csv(cls, purchase_file, store_id, supplier_id=0, field_mapping='', invoice_number='', create_product=False, scrape=False):
    import pandas as pd
    from django.db import transaction

    # 原有CSV解析逻辑保留
    df = df.dropna(how='all')
    lines = len(df)

    for row in df.itertuples():
        status = {
            'total_lines': lines,
            'lines_processed': 1,
            'lines_success': 0,
            'error_lines': []
        }
        # 原有单行数据字段解析逻辑保留

        try:
            # 单条数据用独立事务包裹,异常只回滚单条数据的操作
            with transaction.atomic():
                po, po_created = cls.objects.get_or_create(
                    internal_id=internal_id,
                    supplier=supplier,
                    store_id=store_id,
                    defaults={
                        'purchase_date': purchase_date,
                        'status': status
                    }
                )
                
                if po.completed:
                    continue

                # 原有关联product的逻辑保留

                # 去掉冗余的purchase_order参数和多余的save调用
                if product:
                    pol, pol_created = po.purchaseorderline_set.get_or_create(
                        label=label,
                        ean=row[ean_col + 1],
                        defaults={
                            'amount': row[quantity_col + 1],
                            'label': label,
                            'product': product,
                            'ean': row[ean_col + 1],
                        }
                    )
                else:
                    pol, pol_created = po.purchaseorderline_set.get_or_create(
                        label=label,
                        ean=row[ean_col + 1],
                        defaults={
                            'amount': row[quantity_col + 1],
                            'label': label,
                            'ean': row[ean_col + 1],
                        }
                    )

                po.status['lines_success'] += 1
                po.save()
        except Exception as e:
            # 打印具体异常即可定位真正的报错点(比如PO信号异常、product查询异常、字段约束不满足)
            print(f"第{row.Index}行处理失败,错误:{str(e)}")
            # 按需补充错误行记录逻辑
            continue
  • 第二步:排查PO、POL模型的自定义save方法、pre_save/post_save等信号逻辑,确认没有隐藏的未捕获异常。
  • 第三步:确认PO的status字段的JSON格式符合数据库约束,比如PostgreSQL的JSONField不允许存储不可序列化的Python对象。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.05 16:09:04