您好,登錄后才能下訂單哦!
使用多數據庫最簡單的方法是建立一個數據庫路由模式。默認的路由模式確保對象’粘滯‘在它們原始的數據庫上(例如,從foo 數據庫中獲取的對象將保存在同一個數據庫中)。默認的路由模式還確保如果沒有指明數據庫,所有的查詢都回歸到default數據庫中。
你不需要做任何事情來激活默認的路由模式 —— 它在每個Django項目上’直接‘提供。然而,如果你想實現更有趣的數據庫分配行為,你可以定義并安裝你自己的數據庫路由。
數據庫路由是一個類,它提供4個方法:
db_for_read(model, **hints)
建議model類型的對象的讀操作應該使用的數據庫。
如果一個數據庫操作能夠提供其它額外的信息可以幫助選擇一個數據庫,它將在hints字典中提供。合法的hints 的詳細信息在下文給出。
如果沒有建議,則返回None。
db_for_write(model, **hints)
建議Model 類型的對象的寫操作應該使用的數據庫。
如果一個數據庫操作能夠提供其它額外的信息可以幫助選擇一個數據庫,它將在hints字典中提供。 合法的hints 的詳細信息在下文給出。
如果沒有建議,則返回None。
allow_relation(obj1, obj2, **hints)
如果obj1 和obj2 之間應該允許關聯則返回True,如果應該防止關聯則返回False,如果路由無法判斷則返回None。這是純粹的驗證操作,外鍵和多對多操作使用它來決定兩個對象之間是否應該允許一個關聯。
allow_migrate(db, app_label, model_name=None, **hints)
定義遷移操作是否允許在別名為db的數據庫上運行。如果操作應該運行則返回True ,如果不應該運行則返回False,如果路由無法判斷則返回None。
位置參數app_label 是正在遷移的應用的標簽。
大部分遷移操作設置model_name的值為正在遷移的模型的model._meta.model_name(模型的__name__ 的小寫)。對于RunPython和RunSQL 操作它的值為None,除非這兩個操作使用hint 提供它。
hints 用于某些操作來傳遞額外的信息給路由。
當設置了model_name時,hints 通常通過鍵'model'包含該模型的類。注意,它可能是一個歷史模型,因此不會有自定的屬性、方法或管理器。你應該只依賴_meta。
這個方法還可以用來決定一個給定數據庫上某個模型的可用性。
注意,如果這個方法返回False,遷移將默默地不會在模型上做任何操作。這可能導致你應用某些操作之后出現損壞的外鍵、表多余或者缺失。
Changed in Django 1.8:
allow_migrate的簽名與以前的版本相比發生了顯著更改。有關詳細信息,請參閱deprecation notes。
路由不必提供所有這些方法 —— 它可以省略一個或多個。如果某個方法缺失,在做相應的檢查時Django 將忽略該路由。
例子:
DATABASES = { 'auth_db': { 'NAME': 'auth_db', 'ENGINE': 'django.db.backends.mysql', 'USER': 'mysql_user', 'PASSWORD': 'swordfish', }, 'primary': { 'NAME': 'primary', 'ENGINE': 'django.db.backends.mysql', 'USER': 'mysql_user', 'PASSWORD': 'spam', }, 'replica1': { 'NAME': 'replica1', 'ENGINE': 'django.db.backends.mysql', 'USER': 'mysql_user', 'PASSWORD': 'eggs', }, 'replica2': { 'NAME': 'replica2', 'ENGINE': 'django.db.backends.mysql', 'USER': 'mysql_user', 'PASSWORD': 'bacon', },}
現在我們將需要處理路由。首先,我們需要一個路由,它知道發送auth 應用的查詢到auth_db:
class AuthRouter(object): """ A router to control all database operations on models in the auth application. """ def db_for_read(self, model, **hints): """ Attempts to read auth models go to auth_db. """ if model._meta.app_label == 'auth': return 'auth_db' return None def db_for_write(self, model, **hints): """ Attempts to write auth models go to auth_db. """ if model._meta.app_label == 'auth': return 'auth_db' return None def allow_relation(self, obj1, obj2, **hints): """ Allow relations if a model in the auth app is involved. """ if obj1._meta.app_label == 'auth' or \ obj2._meta.app_label == 'auth': return True return None def allow_migrate(self, db, app_label, model=None, **hints): """ Make sure the auth app only appears in the 'auth_db' database. """ if app_label == 'auth': return db == 'auth_db' return None
我們還需要一個路由,它發送所有其它應用的查詢到primary/replica 配置,并隨機選擇一個replica 來讀取:
import randomclass PrimaryReplicaRouter(object): def db_for_read(self, model, **hints): """ Reads go to a randomly-chosen replica. """ return random.choice(['replica1', 'replica2']) def db_for_write(self, model, **hints): """ Writes always go to primary. """ return 'primary' 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 def allow_migrate(self, db, app_label, model=None, **hints): """ All non-auth models end up in this pool. """ return True
最后,在設置文件中,我們添加如下內容(替換path.to.為該路由定義所在的真正路徑):
DATABASE_ROUTERS = ['path.to.AuthRouter', 'path.to.PrimaryReplicaRouter']
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。