• django 配置 多数据库


    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根据自己的规则来获得不同的数据库。

  • 相关阅读:
    倒车入库:场地模型线序
    Mini440之uboot移植之实践NAND启动(四)
    数据库mysql转为postgresql变动
    嵌入式Linux之vs code开发环境搭建
    Chrome Version 19.0.1055.1 dev Flash Missing plugin的修复
    再次解决,android 2.3运行凯立德问题
    笔记本双屏系统的组建
    gitfatal: unable to access : The requested URL returned error: 403
    C++ 学习拾遗 —— 点滴记录C++学习过程中遇到的问题以及整理
    linux 常用命令
  • 原文地址:https://www.cnblogs.com/zealousness/p/8757150.html
Copyright © 2020-2023  润新知