Django CheckConstraint:反向外键查找的元素不能为空
Django CheckConstraint: Elements of reverse ForeignKey lookup must not be empty
我有这些模型:
class Container(models.Model):
...
class Meta:
constraints = [
models.CheckConstraint(
check=~Q(elements=None),
name='container_must_have_elements'
),
]
class Element(models.Model):
container = models.ForeignKey(Container),
related_name='elements',
on_delete=models.CASCADE
)
我想强制每个 Container
对象必须至少有一个 Element
通过外键关系引用它的约束。
如您所见,我已经添加了检查约束。但是,Q
对象上的否定运算符 ~
似乎是被禁止的。当我尝试应用生成的迁移时,我得到 django.db.utils.NotSupportedError: cannot use subquery in check constraint
。
没有否定运算符,约束似乎是有效的(它只是由于数据完整性错误而失败)。
是否有另一种方式可以表达此约束以使其受到 CheckConstraint
的支持?
(例如,有没有办法检查 elements
的集合是否不为空?)
我将通过总结问题的评论来回答我自己的问题。
检查约束旨在检查 table 中的每一行的条件,它只考虑行本身,不会为此加入其他 table。
坚持使用 SQL,可以通过在 SQL 中定义一个函数并从约束内调用它来制定包括其他 table 的扩展约束。
Django 2.2 中引入的 CheckConstraint
仅通过使用 Q
对象支持 table 本身的条件。
更新:
从 Django 3.1 开始,CheckConstraint
s 不仅支持 Q
对象,还支持布尔值 Expression
s。见 Django 3.2 documentation.
我有这些模型:
class Container(models.Model):
...
class Meta:
constraints = [
models.CheckConstraint(
check=~Q(elements=None),
name='container_must_have_elements'
),
]
class Element(models.Model):
container = models.ForeignKey(Container),
related_name='elements',
on_delete=models.CASCADE
)
我想强制每个 Container
对象必须至少有一个 Element
通过外键关系引用它的约束。
如您所见,我已经添加了检查约束。但是,Q
对象上的否定运算符 ~
似乎是被禁止的。当我尝试应用生成的迁移时,我得到 django.db.utils.NotSupportedError: cannot use subquery in check constraint
。
没有否定运算符,约束似乎是有效的(它只是由于数据完整性错误而失败)。
是否有另一种方式可以表达此约束以使其受到 CheckConstraint
的支持?
(例如,有没有办法检查 elements
的集合是否不为空?)
我将通过总结问题的评论来回答我自己的问题。
检查约束旨在检查 table 中的每一行的条件,它只考虑行本身,不会为此加入其他 table。
坚持使用 SQL,可以通过在 SQL 中定义一个函数并从约束内调用它来制定包括其他 table 的扩展约束。
Django 2.2 中引入的 CheckConstraint
仅通过使用 Q
对象支持 table 本身的条件。
更新:
从 Django 3.1 开始,CheckConstraint
s 不仅支持 Q
对象,还支持布尔值 Expression
s。见 Django 3.2 documentation.