zealousness

django 配置 多数据库

2018-04-09 08:44  ZealouSnesS  阅读(2008)  评论(0编辑  收藏  举报

django多数据库

阅读spider platform时发现前端项目中使用了多数据库,那么django实现多数据库需要哪些配置呢,又如何使用呢?

定义及路由机制

定义

settings里面的DATABASES是一个字典,用于定义需要的数据库,如下,一共定义了两个数据库。

 

DATABASES = {

    \'default\': {

        \'NAME\': \'app_data\',

        \'ENGINE\': \'django.db.backends.postgresql_psycopg2\',

        \'USER\': \'postgres_user\',

        \'PASSWORD\': \'s3krit\'

    },

    \'user1\': {

        \'NAME\': \'user1_data\',

        \'ENGINE\': \'django.db.backends.mysql\',

        \'USER\': \'mysql_user\',

        \'PASSWORD\': \'priv4te\'

    }

 \'user2\': {

        \'NAME\': \'user2_data\',

        \'ENGINE\': \'django.db.backends.mysql\',

        \'USER\': \'mysql_user\',

        \'PASSWORD\': \'priv4te\'

    }

}

那么什么时候调用default什么时候调用users数据库呢,这就需要下面的路由。

 

路由注册

 

class User1Router(object):

    """ A router to control all database operations on models in the auth application. """

    def db_for_read(self, model, **hints):

        """ Attempts to read auth models go to auth_db. """

        if model._meta.app_label == \'auth\':

            return \'user1\'

        return None

 

    def db_for_write(self, model, **hints):

        """ Attempts to write auth models go to auth_db. """

        if model._meta.app_label == \'auth\':

            return \'user1\'

        return None

 

    def allow_relation(self, obj1, obj2, **hints):

        """ Allow relations if a model in the auth app is involved. """

        if obj1._meta.app_label == \'auth\' or \

           obj2._meta.app_label == \'auth\':

           return True

        return None

 

    def allow_syncdb(self, db, model):

        """ Make sure the auth app only appears in the \'auth_db\' database. """

        if db == \'auth_db\':

            return model._meta.app_label == \'auth\'

        elif model._meta.app_label == \'user1\':

            return False

        return None

 

 

 

 class User2Router(object):

    """ A router to control all database operations on models in the auth application. """

    def db_for_read(self, model, **hints):

        """ Attempts to read auth models go to auth_db. """

        if model._meta.app_label == \'auth2\':

            return \'user2\'

        return None

 

    def db_for_write(self, model, **hints):

        """ Attempts to write auth models go to auth_db. """

        if model._meta.app_label == \'auth2\':

            return \'user2\'

        return None

 

    def allow_relation(self, obj1, obj2, **hints):

        """ Allow relations if a model in the auth app is involved. """

        if obj1._meta.app_label == \'auth\' or \

           obj2._meta.app_label == \'auth\':

           return True

        return None

 

    def allow_syncdb(self, db, model):

        """ Make sure the auth app only appears in the \'auth_db\' database. """

        if db == \'auth_db\':

            return model._meta.app_label == \'auth2\'

        elif model._meta.app_label == \'user2\':

            return False

        return None

 

User1Router的路由逻辑是,如果model所属的app是auth的话,就使用user1数据库,否则就使用其他的;User2Router的逻辑类似。

如何注册路由

光定义路由程序无法调用到,还需要注册到django中,在settings中定义

DATABASE_ROUTERS = [\'path.to.User1Router\' , \'path.to.User2Router\']

path.to:是User1Router的完整python包路径,所以,User1Router不一定要在settings中实现,可以在任何地方。

路由机制

那么django是如何选择其中一个路由的呢?

1. django按照注册的顺序轮询DATABASE_ROUTERS,所以首先验证User1Router是否返回了非空字符串,如果是,则使用User1Router;如果不是则接着验证后面的Router;

2. 同样验证User2Router,如果User2Router返回了非空字符串,则使用User2Router;如果不是则使用default数据库;

3. 所以可以看出,路由注册的顺序是会影响最后的结果的,注册在前面的路由会优先被使用;

自动路由和手动路由

上面定义的Router是自动路由,意思是django会自动轮询所注册的路由器,某个model会保存在哪个数据库,是django通过注册的Router自动获得的,在编码中你不需要指定;

手动路由,则是你可以在编码中指定某个model要保存到哪个数据库。

而且手动路由也有性能方面的优点,如果定义了很多个数据库,每次保存或者读取model都要把轮询一遍路由列表,显然效率有些低,如果程序逻辑清楚的知道当前的代码应该连接哪个数据库,显示指定的方式显然效率更高。

手动路由

查询

使用using函数,参数就是要查询的数据库

 

User.objects.using(\'user1\').all()

保存或者更新

使用save的using参数,值就是要使用的数据库

 

 

>>> my_object.save(using=\'user1\')

删除

使用delete的using参数

>>> user_obj.delete(using=\'user1\')

 

分库技术

下面紧紧介绍分库的思路。

垂直分库

即一个app对应一个数据库,上面自动路由的例子就是一个垂直分库的例子,auth1使用user1数据库,auth2使用user2数据库。当然也可以使用手动路由。

水平分库

水平分库建议使用手动路由,因为每个model的分库机制可能都不一样,自动路由实现起来有些麻烦会造成性能不高,而手动路由,每个model根据自己的规则来获得不同的数据库。

分类:

技术点:

相关文章:

  • 2021-05-28
  • 2021-12-03
  • 2021-08-08
  • 2021-08-08
  • 2021-08-08
  • 2021-08-08
  • 2021-08-08
猜你喜欢
  • 2021-08-08
  • 2021-08-08
  • 2021-11-01
  • 2021-08-08
  • 2021-08-08
  • 2021-08-08
  • 2021-10-08
相关资源
相似解决方案