[英]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
生成了模型。 作为证明,如果我在db1
和default
之间交换数据库配置,我可以毫无问题地访问该对象。
任何帮助高度赞赏!
我发现步骤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.