Django ORM - 关于Router.allow_relation()的混淆

sof*_*lay 10 python database django

在新版本的Django的文档中,文本中的内容与显示的代码之间存在歧义.

在描述多数据库配置的部分中,它介绍了路由器配置,并且有一个方法:

allow_relation(obj1, obj2, **hints)

如果应该允许obj1和obj2之间的关系,则返回True;如果应该阻止关系,则返回False;如果路由器没有意见,则返回None.这纯粹是一种验证操作,由外键和多对多操作用于确定两个对象之间是否应该允许关系.

在文档的最后有这样的:

Django目前不提供跨越多个数据库的外键或多对多关系的任何支持.如果已使用路由器将模型分区到不同的数据库,则由这些模型定义的任何外键和多对多关系必须位于单个数据库的内部.

这是因为参照完整性.为了维护两个对象之间的关系,Django需要知道相关对象的主键是有效的.如果主键存储在单独的数据库中,则无法轻松评估主键的有效性.

但作为示例给出的路由器代码如下:

def allow_relation(self, obj1, obj2, **hints):
     """
     Relations between objects are allowed if both objects are
     in the primary/replica pool.
     """
     db_list = ('primary', 'replica1', 'replica2')
     if obj1._state.db in db_list and obj2._state.db in db_list:
         return True
     return None
Run Code Online (Sandbox Code Playgroud)

因此,即使对象来自不同的数据库,软件也允许这种关系.

有谁知道这意味着什么?

谢谢.

Kev*_*nry 9

这是一个很好的问题,我同意多数据库文档并不像它们那样清晰.

需要记住的是,多数据库基本上有两种用例:将不同的数据(模型)放在不同的数据库上; 并设置主/副本数据库结构.这些用例都在文档的主要示例中表示.

在不同的数据场景中,您肯定希望allow_relation()拒绝两个不同数据库之间的任何关系.但是在主副本方案中,您在所有数据库上拥有相同的数据,因此可以允许任何数据库之间的关系.

所以,如果你从一个模型实例replica1来自与另一个replica2(由于数据库读取的随机选择),这将是确定以允许由于相同的数据是否存在于他们之间的关系primary,而这也正是新的模型数据将被写入.

  • @softwareplay:*relation*here指的是,例如,从一个模型实例到另一个模型实例的`ForeignKey`(比如引用`Author`实例的`Article`实例).如果这些表保存在不同的数据库中,那么就不能允许`ForeignKey`,因为无法在不同的数据库中强制执行约束.但是在主/副本方案中,两个表都在同一个数据库中表示,只是您可能从不同的副本中获取了两个实例.在这种情况下,允许关系是可以的,因为所有数据都将写入主数据库. (2认同)