簡體   English   中英

Django多數據庫路由

[英]Django multi-database routing

我一直在使用手動數據庫選擇來處理具有兩個單獨數據庫的項目。 我已經在設置中定義了我的數據庫。

經過進一步閱讀后,似乎數據庫路由實際上是解決此問題的方法。 但是,在閱讀了此處的文檔和一些相關帖子后,我比以往任何時候都更加困惑。

在我的設置中,我有:

DATABASES = {
    'default': {
       .... 
    },
    'my_db2': {
       ....
    }
}

DATABASE_ROUTERS = ['myapp2.models.MyDB2Router',]

我知道我必須像這樣定義我的路由器類(我認為myapp2.models.py文件中):

class MyDB2Router(object):
"""A router to control all database operations on models in
the myapp2 application"""

def db_for_read(self, model, **hints):
    if model._meta.app_label == 'myapp2':
        return 'my_db2'
    return None

def db_for_write(self, model, **hints):
    if model._meta.app_label == 'myapp2':
        return 'my_db2'
    return None

def allow_relation(self, obj1, obj2, **hints):
    if obj1._meta.app_label == 'myapp2' or obj2._meta.app_label == 'myapp2':
        return True
    return None

def allow_syncdb(self, db, model):

    if db == 'my_db2':
        return model._meta.app_label == 'myapp2'
    elif model._meta.app_label == 'myapp2':
        return False
    return None

然后呢? 每個模型都需要一個meta.app_label還是自動的? 除此之外,我仍然收到一個錯誤:

django.core.exceptions.ImproperlyConfigured:導入數據庫路由器時出錯 JournalRouter:“無法導入名稱連接

任何人都可以幫助我了解發生了什么以及出了什么問題? 非常感謝任何幫助。

好的,所以我剛剛解決了我自己的問題。 路由器類進入/myapp2下名為 routers.py 的單獨文件。 不需要meta.app_label因為我猜它是自動分配的。 希望這可以幫助某人。 我還在此處記錄了該過程。

沒有幫助我,所以我做了一些調試。 也許結果可以為某人節省一些痛苦。 :) django 1.4中的問題是django嘗試導入自定義路由類時出現的循環引用。
這發生在django.db.utils.ConnectionRouter 在我的情況下,應用程序的__init__.py導入了一個模塊( tastypie.apitastypie.api ),然后(並通過一個長鏈)導入了django.db.models 這本身並不壞,但models試圖從django.db導入connection ,而這恰好依賴於ConnectionRouter 這正是我們旅程開始的地方。 因此錯誤。

這被描述為 django < 1.6 中的一個錯誤: https : //code.djangoproject.com/ticket/20704並且有一個很好的小變更集應該在 django 1.6 中修復它: https : //github.com/django /django/commit/6a6bb168be90594a18ab6d62c994889b7e745055

然而,我的解決方案是簡單地將routers.py從應用程序目錄移動到項目目錄。 那里沒有討厭的依賴。

另一個要忽略的錯誤是在路由器中導入模型,這將導致相同的錯誤,即使路由器是在不同的文件中定義的。

如果您有一個使用多個數據庫的應用程序,您可以在每個應用程序和每個表的基礎上進行路由。 例如,如果您的應用程序是“控制台”並且您只希望“PoolServers”模型來自不同的后端,您可以將其放在 router.py 中

class PoolServerRouter(object): 
def db_for_read(self, model, **hints):
    "Point only reads to poolserver  model to 'hamburger'"
    if model._meta.app_label == 'console' and model._meta.db_table == 'PoolServers':
        return 'hamburger'
    return 'default'

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM