gpt4 book ai didi

mysql - save() 上的 Django + MySQL 完整性错误

转载 作者:行者123 更新时间:2023-11-29 12:55:23 25 4
gpt4 key购买 nike

我有以下代表 IP 地址的模型:

class Ip(models.Model):
ip = models.CharField(max_length=20, primary_key=True)
...

进程正在向函数发送 IP 参数,该函数应将 Ip 行更新到数据库中。

这工作正常,直到进程开始用 IP“轰炸”,有时(大约每几百个请求中就有 1 个)会抛出以下错误:

完整性错误:(1062,“ key “PRIMARY”的重复条目“1.2.3.4””)

为什么会发生这种情况?
当该行已经存在(它被定义为主键)时,为什么 Django 会尝试 INSERT?
如何在不手动选择然后决定是插入还是更新的情况下解决这个问题?

我们正在使用Django 1.5.1

编辑:
以下是我们如何进行更新插入:

obj = Ip(ip='1.2.3.4', ...)
obj.save()

根据文档(以及我们的经验),这应该基于主键 ip 执行 UPSERT 操作,该主键始终具有值。

最佳答案

save 方法受到有关主键的竞争条件的影响。它首先判断是否存在具有该主键的记录,如果存在则执行更新语句,否则执行插入语句。如果并发请求在这两个查询之间插入新记录,则会出现完整性错误。

以下将处理竞争条件(除非在查询之间删除记录):

import sys
from django.utils import six

try:
obj.save()
except IntegrityError:
# The save might have been subject to a race condition.
# If it is, a record with this object's pk exists, so try to update it.
exc_info = sys.exc_info()
try:
obj.save(force_update=True)
except:
six.reraise(*exc_info)

如果出现其他问题,这将引发第一个初始异常,因此除了由该竞争条件引起的错误之外,没有隐藏的 IntegrityError 错误。我知道对于简单的保存来说有点冗长,但您始终可以重写模型上的 save 方法来为您执行此操作。

关于mysql - save() 上的 Django + MySQL 完整性错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24141498/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com