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貌似没我写的详细。。。。

Django Multi-DB Router
阅读(5013) 评论(0) 2012-10-16
输入类似这样的地址 "name@something.com"
输入类似这样的地址"http://someaddress.com"
验证码 不区分大小写(看不清)