我的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中完成的?
答案 0 :(得分:1)
这是我获得您要求的现有记录的方式。 在这种情况下,我有
的MyModelunique_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'))
答案 1 :(得分:0)
for b in bs:
p = Business.objects.get_or_create(name=b['name'])
p.update(**b)
p.save()
我想无论如何
答案 2 :(得分:0)
我尝试了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'])
,但这仅适用于您确定知道它是名称冲突的情况。