2016-02-15 55 views
4

在Django新版本的文檔中,文字和顯示的代碼之間存在歧義。Django ORM - 關於Router.allow_relation()的混淆

在描述它充分說明了路由器配置的多數據庫配置的部分,有一個方法:

allow_relation(obj1, obj2, **hints)

返回真,如果OBJ1之間的關係和obj2的應該被允許,假如果該關係應該被阻止,或者無,如果路由器有 沒有意見。這純粹是一種驗證操作,由外鍵 和多對多操作使用以確定兩個對象之間是否允許關聯應爲 。

在文檔末尾有這樣:

的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 

所以,即使對象是來自不同數據庫之間的關係是由軟件允許的。

有人知道這意味着什麼嗎?

謝謝。

回答

5

這是一個很好的問題,我同意多數據庫文檔並不盡如人意。

需要記住的是,基本上有兩種用於多數據庫的用例:將不同的數據(模型)放在不同的數據庫上;並設置主/副本DB結構。這些用例在文檔的主要示例中都有描述。

在不同數據場景中,您肯定希望allow_relation()拒絕兩個不同數據庫之間的任何關係。但是在主副本場景中,所有數據庫都具有相同的數據,因此可以允許其中任何一個數據庫之間的關係。

所以,如果你replica1,另一名來自replica2得到一個模型實例(由於數據庫讀取的隨機選擇),這將是確定允許在primary存在,因爲相同的數據之間的關係,而這也正是新的模型數據將被寫入。

+0

我還沒有完全得到點,所以我以後會接受你的答案,但它是有幫助的。(我的意思是我不明白什麼意思,讓數據庫之間的關係,如果它的數據是一樣的。你讓一個副本鏈接到 – softwareplay

+1

@softwareplay本身???只是想知道)的複製:* *的關係在這裏指的是,例如,一個'ForeignKey'從一個模型實例到另一個(說的'文章引用'Author'實例的實例)。如果這些表保存在不同的數據庫中,那麼您不能允許「ForeignKey」,因爲無法在不同數據庫之間強制執行約束。但是在主/副本場景中,兩個表都在同一個數據庫中表示,只是您可能已經從不同副本中提取了兩個實例。在這種情況下,允許關係是很好的,因爲所有數據都將寫入主數據庫。 –