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

时间:2016-02-15 08:19:33

标签: python django database

在新版本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

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

有谁知道这意味着什么?

感谢。

1 个答案:

答案 0 :(得分:8)

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

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

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

因此,如果您从replica1获得一个模型实例而从replica2获得另一个模型实例(由于随机选择数据库进行读取),因为相同的数据可以允许它们之间的关系存在于primary,以及将要写入新模型数据的位置。