Django multi-db router小结
利用django做multi-db项目时,还是蛮方便的,除了使用using语句在编程中指定数据库,还可以通过编写router的方法更有序地解决这个问题。
下面以Oracle举例,首先,在settings.py里应该有这些设置分别指向不同的数据库:
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.oracle',
'NAME': 'YourDBName',
'USER': 'user1',
'PASSWORD': 'user1',
'HOST': '172.0.0.0',
'PORT': '1521',
},
'db1': {
'ENGINE': 'django.db.backends.oracle',
'NAME': 'YourDBName',
'USER': 'user1',
'PASSWORD': 'user1',
'HOST': '172.0.0.0',
'PORT': '1521',
},
'db2': {
'ENGINE': 'django.db.backends.oracle',
'NAME': 'YourDBName',
'USER': 'user2',
'PASSWORD': 'user2',
'HOST': '172.0.0.0',
'PORT': '1521',
},
}
然后,在各个application下放一个routers.py(理论上你可以放在任意地方,但是我们的开发规范是放在application下,比如你有一个application名为"app1",你在这下面建一个routers.py文件,然后在里面写如下代码:
__author__ = 'Alan'
class App1Router(object):
"""A router to control all database operations on models in
the app1 application"""
def db_for_read(self, model, **hints):
if model._meta.app_label == 'app1':
return 'db1'
return None
def db_for_write(self, model, **hints):
if model._meta.app_label == 'app1':
return 'db1'
return None
def allow_relation(self, obj1, obj2, **hints):
if obj1._meta.app_label == 'app1' or obj2._meta.app_label == 'app1':
return True
return None
def allow_syncdb(self, db, model):
if db == 'db1':
return model._meta.app_label == 'app1'
elif model._meta.app_label == 'app1':
return False
return None
好了,如果你的这个app1是固定往一个数据库里读写及同步数据结构,这个就已经足够了,但是,如果碰到一对多或者多对一的情况怎么办?就是当需要一个application往多个库里同步数据结构,或者是多个application往一个数据库里同步表结构时怎么办?
一个application往多个数据库里同步数据结构时,这么写router:
__author__ = 'Alan'
class App1ToDB1AndDB2Router(object):
"""A router to control sync one app to multi-db
"""
def allow_syncdb(self, db, model):
if db == 'db1' or db == 'db2':
return model._meta.app_label == 'app1'
elif model._meta.app_label == 'app1':
return False
return None
多个application往一个数据库里同步数据结构时,这么写router:
__author__ = 'Alan'
class SyncMultiAppToDBRouter(object):
def allow_syncdb(self, db, model):
if db == 'db1':
flag = False
if model._meta.app_label == 'app1':
flag = True
if model._meta.app_label == 'app2':
flag = True
return flag
elif model._meta.app_label == 'app1' or model._meta.app_label == 'app2':
return False
return None
然后在settings.py里再加上这样的配置:
DATABASE_ROUTERS = ['path.to.SyncMultiAppToDBRouter',
'app1.routers.App1Router', ]
同步数据结构时就可以用以下命令同步了
python manage.py syncdb #sync the default db
python manage.py syncdb --database=db1 #sync the db1
python manage.py syncdb --database=db2 #sync the db2
更多请参考官方文档https://docs.djangoproject.com/en/dev/topics/db/multi-db/,事实上官方文档关于Router貌似没我写的详细。。。。