【问题标题】:How to get the record causing IntegrityError in Django如何在 Django 中获取导致 IntegrityError 的记录
【发布时间】:2014-07-25 20:27:26
【问题描述】:

我的 django 模型中有以下内容,我将其与 PostgresSql 一起使用

class Business(models.Model):
    location = models.CharField(max_length=200,default="")
    name = models.CharField(max_length=200,default="",unique=True)

在我看来,我有:

for b in bs: 
    try:
        p = Business(**b)
        p.save()
    except IntegrityError:
        pass

当应用程序运行并触发 IntegrityError 时,我想获取已插入的记录以及触发错误的对象(我假设为“p”)并更新位置字段。

在伪代码中:

for b in bs: 
    try:
        p = Business(**b)
        p.save()
    except IntegrityError:

     EXISTING_RECORD.location = EXISTING_RECORD.location + p.location
     EXISTING_RECORD.save()

这在 django 中是如何完成的?

【问题讨论】:

  • 这是您的整个模型,还是您简化以使问题更容易?或者更直接地说……如果两个企业名称相同,是否唯一会导致完整性错误?
  • 嗨 Foon,这是简化的,但 name 是唯一的唯一键(id 除外)- Bill

标签: python django postgresql


【解决方案1】:

这是我获得您要求的现有记录的方式。 在这种情况下,我有 MyModel 与

unique_together = (("owner", "hsh"),)

我使用正则表达式来获取导致问题的现有记录的所有者和 hsh。

import re
from django.db import IntegrityError


try:
    // do something that might raise Integrity error

except IntegrityError as e:

    #example error message (e.message): 'duplicate key value violates unique constraint "thingi_userfile_owner_id_7031f4ac5e4595e3_uniq"\nDETAIL:  Key (owner_id, hsh)=(66819, 4252d2eba0e567e471cb08a8da4611e2) already exists.\n'

    import re
    match = re.search( r'Key \(owner_id, hsh\)=\((?P<owner_id>\d+), (?P<hsh>\w+)\) already', e.message)
    existing_record = MyModel.objects.get(owner_id=match.group('owner_id'), hsh=match.group('hsh'))

【讨论】:

    【解决方案2】:

    我尝试了 get_or_create,但这并不能完全按照您想要的方式工作(如果您使用名称和位置进行 get_or_create,您仍然会收到完整性错误;如果您按照 Joran 的建议进行操作,除非您超载更新,它将覆盖位置而不是附加。

    这应该按照你想要的方式工作:

    for b in bs: 
        bobj, new_flag = Business.objects.get_or_create(name=b['name'])
        if new_flag:
           bobj.location = b['location']
        else:
           bobj.location += b['location'] # or possibly something like += ',' + b['location'] if you wanted to separate them
        bobj.save()
    

    如果您可以有多个唯一约束,能够检查 IntegrityException(类似于IntegrityError: distinguish between unique constraint and not null violations 中接受的答案,这将是很好的(并且可能,但我没有尝试过)也有似乎只是 postgres 的缺点)来确定违反了哪些字段。请注意,如果您想遵循您的原始框架,您可以在您的异常中执行collidedObject = Business.objects.get(name=b['name']),但这仅适用于您确定这是名称冲突的情况。

    【讨论】:

      【解决方案3】:
      for b in bs: 
          p = Business.objects.get_or_create(name=b['name'])
          p.update(**b)
          p.save()
      

      我觉得还是

      【讨论】:

        猜你喜欢
        • 2012-09-09
        • 1970-01-01
        • 2020-04-01
        • 1970-01-01
        • 1970-01-01
        • 2018-06-17
        • 1970-01-01
        • 2011-09-16
        • 1970-01-01
        相关资源
        最近更新 更多