【问题标题】:Why does Django get_or_create cause this IntegrityError?为什么 Django get_or_create 会导致这个 IntegrityError?
【发布时间】:2011-09-16 00:25:06
【问题描述】:

我有一个模型,上面有这个字段:
token = models.CharField(max_length=32, default="", unique=True, null=False, db_index=True)

在 save() 方法中,我使用此方法将此字段设置为 32 个字符的随机字符串:

def save(self, *args, **kwargs):
    if (self.token is None or len(self.token) == 0):
        self.token = random_identifier()
    super(SessionPassthrough, self).save(*args, **kwargs)

def random_identifier(n=32):
    """ Generate a random identifier of length n. 

    From http://stackoverflow.com/questions/2257441/python-random-string-generation-with-upper-case-letters-and-digits"""
    return ''.join(random.choice(string.ascii_lowercase + string.digits) for x in range(n))

但是,每当我尝试创建模型的新实例时都会收到此错误:
IntegrityError: duplicate key value violates unique constraint "wakelytics_sessionpassthrough_token_key"

为了创建实例,我调用了这个方法:

@staticmethod
def for_session(session):
    sp, c = SessionPassthrough.objects.get_or_create(session=session)
    return sp

get_or_create() 是否在写入数据库之前调用方法的 save() 函数? 回答:是的

每当我第一次使用session 调用该方法时,我都会收到一个IntegrityError,并在几分钟内继续收到错误。然后它会正确返回。这是什么原因造成的?

【问题讨论】:

  • 确实知道,即使是随机例程也可以选择一个已经存在的值......对吗?
  • 我知道。但每次?然后它停止抛出错误?
  • 随机的。你不知道什么时候它会选择一个不在你的数据库中的值。
  • 但在这种情况下,它会返回而不会出现错误sometimes,而现在它在前几次/分钟内可靠地失败,然后成功。

标签: python django orm model


【解决方案1】:

是的。

https://docs.djangoproject.com/en/dev/ref/models/querysets/#get-or-create

来自文档:

新对象将大致按照这个算法创建:

defaults = kwargs.pop('defaults', {})
params = dict([(k, v) for k, v in kwargs.items() if '__' not in k])
params.update(defaults)
obj = self.model(**params)
obj.save()

【讨论】:

    【解决方案2】:

    当然可以。它的部分合同是它返回一个确实存在的模型,并且为了做到这一点,它必须保存。

    编辑:

    您收到该错误是因为该值已存在于数据库中。

    【讨论】:

    • 如果它已经存在,get_or_create 不会简单地返回它吗?为什么会引发错误?
    • 因为session 不同,所以它是一个单独的行。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-02-25
    • 2014-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-10-02
    相关资源
    最近更新 更多