Django 1.2中的多个数据库配置
希望这个问题比较简单。
我在理解Django 1.2的新多数据库功能的文档时遇到了一些麻烦。主要是,我找不到一个关于如何在模型中实际使用第二个数据库的例子。
当我在models.py中定义一个新类时,怎么指定我想连接哪个数据库呢?
我的settings.py大概是这样的 -
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'modules',
'USER': 'xxx',
'PASSWORD': 'xxx',
},
'asterisk': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'users',
'USER': 'xxxx',
'PASSWORD': 'xxxx',
}
}
补充:我之前看路由的文档时有点傻。如果其他人也遇到这个问题,建议你在放弃之前多读几遍文档!
3 个回答
8
这是对乔丹上面回答的补充。对于第二个选项,allow_syncdb 方法的工作原理如下:
def allow_syncdb(self, db, model):
if hasattr(model,'connection_name'):
return model.connection_name == db
return db == 'default'
25
是的,这个有点复杂。
其实有很多种方法可以实现这个功能。基本上,你需要一种方式来指明哪些模型和哪个数据库是关联的。
第一种选择
下面是我使用的代码,希望对你有帮助。
from django.db import connections
class DBRouter(object):
"""A router to control all database operations on models in
the contrib.auth application"""
def db_for_read(self, model, **hints):
m = model.__module__.split('.')
try:
d = m[-1]
if d in connections:
return d
except IndexError:
pass
return None
def db_for_write(self, model, **hints):
m = model.__module__.split('.')
try:
d = m[-1]
if d in connections:
return d
except IndexError:
pass
return None
def allow_syncdb(self, db, model):
"Make sure syncdb doesn't run on anything but default"
if model._meta.app_label == 'myapp':
return False
elif db == 'default':
return True
return None
这个方法是我创建一个文件,文件名就是要使用的数据库名,这个文件里放着我的模型。在你的情况下,你需要创建一个叫 asterisk.py
的文件,放在和你应用的模型同一个文件夹里。
在你的 models.py
文件里,你需要添加
from asterisk import *
然后当你实际请求这个模型的记录时,过程大概是这样的:
records = MyModel.object.all()
- 模型
MyModel
的模块是myapp.asterisk
- 有一个叫“asterisk”的连接,所以用它代替“default”
第二种选择
如果你想对每个模型选择数据库有更细致的控制,可以使用类似这样的方式:
from django.db import connections
class DBRouter(object):
"""A router to control all database operations on models in
the contrib.auth application"""
def db_for_read(self, model, **hints):
if hasattr(model,'connection_name'):
return model.connection_name
return None
def db_for_write(self, model, **hints):
if hasattr(model,'connection_name'):
return model.connection_name
return None
def allow_syncdb(self, db, model):
if hasattr(model,'connection_name'):
return model.connection_name
return None
然后对于每个模型:
class MyModel(models.Model):
connection_name="asterisk"
#etc...
注意,我还没有测试这个第二种选择。