繁体   English   中英

如何在Django 1.4中使用DB路由器

[英]How to use DB router in Django 1.4

我一直在尝试将Django 1.4.3设置为使用多个DB,但对于我的生活,我无法让它工作。 我阅读了SO上的文档和帖子,并做了以下事情:

1)settings.py添加第二个数据库配置,如下所示:

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': '/tmp/django.db',
        'USER': '',
        'PASSWORD': '',
        'HOST': '',
        'PORT': '',
    },
    'db1' : {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'db1',
        'USER': 'fake',
        'PASSWORD': 'fake',
        'HOST': 'fake.host.com',
        'PORT': '3306',
    },
}

2)创建一个routers.py并定义一个DB路由器,如下所示
(注意:根据SO帖子,如果你在models.py定义一个DB路由器,路由器将无法工作)

class DBRouter(object):
    def db_for_read(self, model, **hints):
        return 'db1'

    def db_for_write(self, model, **hints):
        return 'db1'

    def allow_syncdb(self, db, model):
        return 'db1'

3)将以下行添加到settings.py
(注意:根据SO帖子,这些行必须在DATABASES配置之后

from django.db import connections
DATABASE_ROUTERS = ['fakeproject.routers.DBRouter',]

这是错的。 不要在这里放置from django.db import connections ,因为它会阻止路由器注册

我的症状:
显然,我的所有呼叫都是通过默认数据库路由的。 详情如下:

  • 两个数据库设置都有效(我可以成功执行manage.py indpectdb --database db1

  • DATABASE_ROUTERS设置不会产生任何抱怨(即使我把错误的路径放到DB路由器,甚至是非字符串对象)

  • 当我尝试通过manage.py shell访问我的对象时,我可以执行MyModel.objects.all()但是当我实际尝试迭代它时,我被告知no such table 默认DB没有该表,但是'db1'显然有它,因为我使用了inspectdb生成了模型。 作为证明,如果我在db1default之间交换数据库配置,我可以毫无问题地访问该对象。

任何帮助高度赞赏!

我发现步骤3“ from django.db import connections ”中的语句阻止了DB路由器的注册。 当我删除此语句时,路由器已注册,并且东西开始按预期工作。

我认为问题可能是因为你的routers.py只返回对'db1'的引用,但正如你所说,你只是被路由到'default'我不确定(我希望它是唯一路由到'db1'

routers.py创建一个主路由器类,然后为每个数据库创建子类 - 并使用app_label字符串进行初始化,以便将它们分开。

class MasterRouter(object):
    def __init__(self, app_label):
        super(MasterRouter, self).__init__()
        self.app_label = app_label

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

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

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

    def allow_syncdb(self, db, model):
        if db == 'default':
            return model._meta.app_label == self.app_label
        elif model._meta.app_label == self.app_label:
            return False
        return None

class DefaultRouter(MasterRouter):
    def __init__(self):
        super(DefaultRouter, self).__init__('default')

class DB1Router(MasterRouter):
    def __init__(self):
        super(DB1Router, self).__init__('db1')

然后在您的settings.py声明路由器

DATABASE_ROUTERS = [ 'routers.DefaultRouter', 'routers.DB1Router' ]

当然,您可能希望以不同方式设置MasterRouter类覆盖。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM