我试图在联接表上的两个外键之间强制执行约束,但我不知道是否可以使用数据库来完成约束,还是应该通过应用程序或ORM来实现约束。
这是我的桌子:
Dataset
Tag
- Dataset: FK
- name: string (eg: "park", "church", etc)
Place
- Dataset: FK
- latitude
- longitude
PlaceTag (my join table)
- Tag: FK
- Place: FK
- note: string (eg: "this place is my favorite park")
我要强制执行以下约束:每个PlaceTag都有一个Tag和一个Place,它们属于同一个数据集。我应该使用数据库还是我的应用程序执行此操作?还是应该重新构建模型以更轻松地实施此约束?
FWIW,这是一个开源项目,我在这里创建这些表的PR位于:https://github.com/mapseed/api/pull/161/files该项目正在使用Django,如果有帮助的话。
答案 0 :(得分:1)
在Django中“执行”(注意引号)的一种方法是重写PlaceTag
的{{1}}方法。每当save()
时,您都可以在其中引发异常。但您应该注意,在某些情况下Django不会调用模型的自定义self.place.dataset != self.tag.dataset
方法:
save()
方法时。此方法用于批量更新,因此出于性能考虑,直接在数据库级别(reference)进行更新。update()
方法不可用。在这两种情况下,我建议的方法对于强制执行约束将无济于事(因此,引号在开头)。当然这是不一样的,并且不如在数据库级别上强制执行那样强。无论如何,我认为没有一种可移植的方式(即在任何或大多数SQL数据库引擎中都可以使用)强制执行这种条件,因为检查该条件将需要在其他表上进行联接,但是我对此可能是错误的。