繁体   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