【问题标题】:django get_or_create throws Integrity Errordjango get_or_create 抛出完整性错误
【发布时间】:2021-08-08 20:26:24
【问题描述】:

我已阅读此主题: get_or_create throws Integrity Error

但仍然不完全理解 get_or_create 何时返回 FalseIntegrityError

我有以下代码:

django_username = 'me'
user = get_user_model().objects.filter(username=django_username).first()

action_history, action_added = ActionModel.objects.get_or_create(
                date=date_obj,  # date object 
                account_name=unique_name,  # e.g. account1234
                target=follower_obj, # another model in django
                user=user,  # connected django user
                defaults={'identifier': history['user_id']}
            )

虽然模型看起来像:

class ActionModel(models.Model):
    """
    A model to store action history.

    """

    identifier = models.BigIntegerField(
        _("identifier"), null=True, blank=True) # target id
    account_name = models.CharField(_("AccountName"), max_length=150, null=True, blank=True)  # account name of the client
    date = models.DateField(_("Date"), auto_now=False, auto_now_add=False)  # action date
    target = models.ForeignKey(Follower, verbose_name=_("Target"), on_delete=models.CASCADE)  # username of the done-on action
    user = models.ForeignKey(
        settings.AUTH_USER_MODEL,
        on_delete=models.CASCADE,
        null=True,
        editable=False,
        db_index=True,
    )  # django user that performed the action

    class Meta:
        verbose_name = _("Action")
        verbose_name_plural = _("Actions")
        unique_together = [
            ['account_name','date','target'],
        ]

有时它会返回 IntegrityError,有时(当存在唯一约束时,它会在创建时返回 False)。

【问题讨论】:

  • 文档说:> 如果需要创建一个对象并且数据库中已经存在密钥,则会引发 IntegrityError。
  • @MarkR。为什么它没有在创建之前的获取中被捕获?我将所有唯一值发送给它!

标签: django database


【解决方案1】:

你有 unique_together 约束。 假设您在 db 中有包含以下数据的对象 account_name='bob',date='2020-12-12',target='b',user='12'

在你的 get_or_create 方法中你正在这样做

ActionModel.objects.get_or_create(
            date='2020-12-12', 
            account_name='bob',  
            target='b', 
            user="13"
        )

您使用此数据提供了这三个参数,但这次用户是 13,所以 django 找不到任何对象并尝试创建一个,但是使用此参数您无法创建对象,因为存在唯一约束

【讨论】:

  • 我可以将用户添加到唯一约束吗?它会影响现有的数据库吗? unique_together = [ ['account_name','date','target', 'user']
  • 是的,如果符合您的应用程序逻辑,您也可以将用户添加到约束中,但请注意,如果您有 2 个或更多对象存在独特问题,则可能会出现问题
  • 如果发生这种情况,您可以通过过滤和删除违反约束的对象来清除数据库并尝试再次迁移
【解决方案2】:

好的。 我想通了,我发了:

account_name = 'adi'
date = '07-02-21'
target = 'nana1'
user = 'me'

虽然它不存在于特定用户 = 'me' 但用户 = 无:

account_name = 'adi'
date = '07-02-21'
target = 'nana1'
user = None

因此获取失败,创建的尝试复制 unique_together = ['account_name','date','target']。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-10-22
    • 2013-03-18
    • 2021-09-27
    • 2015-06-17
    • 1970-01-01
    • 2016-04-10
    • 2012-11-15
    • 1970-01-01
    相关资源
    最近更新 更多