【问题标题】:IntegrityError not raised on None没有在 None 上引发 IntegrityError
【发布时间】:2017-06-05 19:25:24
【问题描述】:

我有一个具有以下独特约束的模型:

class Record(Model):
    type = ForeignKey(Type, related_name='records')
    code = CharField(max_length=32)
    group = ForeignKey('self', null=True, blank=True, related_name='members')

    class Meta:
        unique_together = ('type', 'code', 'group')

如果两个记录都具有相同的类型和代码,并且都没有组,我希望它们是相同的。我预计会引发完整性错误,但在以下测试用例中不会发生这种情况:

Record.objects.create(type=type_article_structure,
                      code='shoe',
                      group=None)
Record.objects.create(type=type_article_structure,
                      code='shoe',
                      group=None)

如果我为两者填充相同的组,则唯一约束有效:

group = Record.objects.create(type=type_article_structure,
                              code='group')
Record.objects.create(type=type_article_structure,
                      code='shoe',
                      group=group)
Record.objects.create(type=type_article_structure,
                      code='shoe',
                      group=group)

这会导致:

django.db.utils.IntegrityError: UNIQUE constraint failed: md_masterdata_record.type_id, md_masterdata_record.code, md_masterdata_record.group_id

如何确保我在第一种情况下得到相同的错误?

附言。我的测试用例使用 SQLite,我的生产服务器使用 PostgreSQL。

【问题讨论】:

    标签: python django nonetype data-integrity


    【解决方案1】:

    唯一共同约束应用于数据库级别。许多数据库不会相互比较 null 值,因此,让插入操作进入。

    您可以通过覆盖模型中的 clean 方法来修复它。 clean 方法应该用于提供自定义验证或在保存之前修改字段值。另外,请注意 cleanis not invoked when you callsaveon the object. It should be invoked before calling thesave` 方法。

    from django.core.exceptions import ValidationError
    class Record(Model):
        def clean(self):
            # check if exists
            if Record.objects.get(type=self.type,
                              code=self.code,
                              group=self.group):
                  # raise an exception
                  raise ValidationError("Exists")
    

    【讨论】:

    • 感谢您的回答。不幸的是,我不明白这个例子。该代码不应该在方法中吗?
    • 我忘了写方法签名:)
    • 那时我还是不明白。当然,字符串 'shoe' 是一个示例,不应硬编码。我是否可以通过这种方法访问self.code 等?
    • @physicalattraction 我已经用更多描述更新了答案并清理了代码示例。
    • 感谢您的澄清。我想我会在 RecordManager 的 create 方法中添加一个类似的验证,这样我就不必每次保存记录时都调用 clean。
    【解决方案2】:

    1)

    try:
        //somthing
    except IntegrityError as e:
        print("integrity")
    except Exception as e:
        print(e)`
    

    2)检查一下

    record=Record(type=type_article_structure,
                      code='shoe',
                      group=None)
    record.save()
    

    【讨论】:

      猜你喜欢
      • 2019-02-19
      • 2014-05-09
      • 1970-01-01
      • 2016-12-27
      • 1970-01-01
      • 1970-01-01
      • 2014-12-13
      • 2015-02-23
      • 1970-01-01
      相关资源
      最近更新 更多