【问题标题】:Django multi-database routingDjango 多数据库路由
【发布时间】:2011-12-24 15:33:22
【问题描述】:

我一直在使用手动数据库选择来处理一个有两个单独数据库的项目。我已经在设置中定义了我的数据库。

经过进一步阅读,似乎数据库路由实际上是解决这个问题的方法。但是,在阅读了此处的文档和一些相关帖子后,我比以往任何时候都更加困惑。

在我的设置中:

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 因为我猜它是自动分配的。希望这对某人有所帮助。
  • 为您的问题创建一个新答案并接受它。
  • 如果模型是在models.py之外定义的,则只需要使用app_label选项,否则会自动分配。

标签: python django


【解决方案1】:

好的,所以我刚刚解决了我自己的问题。路由器类进入 /myapp2 下名为 routers.py 的单独文件。不需要 meta.app_label,因为我猜它是自动分配的。希望这可以帮助某人。我还记录了这个过程here

【讨论】:

  • 接受你的答案,这样其他人更容易理解这是一个正确的答案。
【解决方案2】:

还有一个错误要省略,就是在路由器中导入模型,这会导致同样的错误,即使路由器是在不同的文件中定义的。

【讨论】:

  • 谢谢 - 这为我节省了很多时间!
  • 这很重要!感谢您的回答。
  • 甚至像from app.models import some_fun 这样简单的东西也会导致这个错误(在 django 1.5 中)。
【解决方案3】:

没有帮助我,所以我做了一些调试。也许结果可以为某人节省一些痛苦。 :) django 1.4 中的问题是当 django 尝试导入自定义路由器类时发生的循环引用。
这发生在django.db.utils.ConnectionRouter。在我的例子中,应用程序的__init__.py 导入了一个模块(准确地说是tastypie.api),然后(并通过一个长链)导入了django.db.models。这本身还不错,但是models 尝试从django.db 导入connection,而这恰好依赖于ConnectionRouter。这正是我们旅程的起点。因此出现错误。

这在 django https://code.djangoproject.com/ticket/20704 并且有一个不错的小变更集应该在 django 1.6 中修复它:https://github.com/django/django/commit/6a6bb168be90594a18ab6d62c994889b7e745055

然而,我的解决方案是简单地将 routers.py 从 app 目录移动到项目目录。那里没有讨厌的依赖。

【讨论】:

  • 这是为我解决的问题(以及来自@Janosch 的提示)
  • 我将路由类移到我的主项目中,这也为我修复了“无法导入名称连接”错误。谢谢!
【解决方案4】:

如果您有一个使用多个数据库的应用程序,您可以基于每个应用程序和每个表进行路由。例如,如果您的应用程序是“控制台”并且您只希望“PoolServers”模型来自不同的后端,您可以将它放在您的 routers.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'

【讨论】:

    猜你喜欢
    • 2017-06-16
    • 1970-01-01
    • 2012-03-28
    • 1970-01-01
    • 1970-01-01
    • 2018-07-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多