【发布时间】:2020-05-27 03:35:23
【问题描述】:
我有这些模型:
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 的集合是否不为空?)
【问题讨论】:
-
请注意,此约束将产生一种循环依赖,因为您无法在没有元素的情况下创建
Container,但要创建Element,您需要一个容器来引用。在我看来,有这个约束是没有意义的 -
是的,你是对的,但仍然可以满足约束:两个模型的对象必须在单个数据库事务中创建。
-
@PeterF 我不太确定这单笔交易。 Container仍然需要先插入db才能获得pk,然后才能插入Element。那么第一次插入不会引发错误,即您确定仅在事务结束时检查约束吗?
-
立即或仅在事务提交后强制执行约束都是可配置的:postgresql.org/docs/9.1/sql-set-constraints.html
-
以下是使用 SQL 的方法:stackoverflow.com/questions/3880698/… 他们需要在 SQL 中定义一个函数。似乎仅使用 python 代码无法对其他表定义约束。
标签: django django-models django-orm check-constraints django-q