gpt4 book ai didi

django使用多个数据库实现

转载 作者:我是一只小鸟 更新时间:2023-04-21 14:31:22 32 4
gpt4 key购买 nike

1、说明:

  在开发 Django 项目的时候,很多时候都是使用一个数据库,即 settings 中只有 default 数据库,但是有一些项目确实也需要使用多个数据库,这样的项目,在数据库配置和使用的时候,就比较麻烦一点.

2、Django使用多个数据库中settings中的DATABASES的设置

  2.1 默认只是用一个数据库时 DATABASES 的设置(以 SQLite 为例) 。

                          DATABASES =
                          
                             {
    
                          
                          
                            '
                          
                          
                            default
                          
                          
                            '
                          
                          
                            : {
        
                          
                          
                            '
                          
                          
                            ENGINE
                          
                          
                            '
                          
                          : 
                          
                            '
                          
                          
                            django.db.backends.sqlite3
                          
                          
                            '
                          
                          
                            ,         
        
                          
                          
                            '
                          
                          
                            NAME
                          
                          
                            '
                          
                          : 
                          
                            '
                          
                          
                            db.sqlite3
                          
                          
                            '
                          
                          
                            ,
    }
}
                          
                        

  2.2 Django 数据库支持的 ENGINE 类型 。

    • 'django.db.backends.postgresql'
    • 'django.db.backends.mysql'
    • 'django.db.backends.sqlite3'
    • 'django.db.backends.oracle'

  2.3 设置了多个数据库后 settings 中的 DATABASES 的设置 。

                          DATABASES =
                          
                             {
    
                          
                          
                            '
                          
                          
                            default
                          
                          
                            '
                          
                          
                            : {
        
                          
                          
                            '
                          
                          
                            ENGINE
                          
                          
                            '
                          
                          : 
                          
                            '
                          
                          
                            django.db.backends.sqlite3
                          
                          
                            '
                          
                          
                            ,
        
                          
                          
                            '
                          
                          
                            NAME
                          
                          
                            '
                          
                          : 
                          
                            '
                          
                          
                            db.sqlite3
                          
                          
                            '
                          
                          
                            ,
    },
    
                          
                          
                            '
                          
                          
                            db1
                          
                          
                            '
                          
                          
                            : {
        
                          
                          
                            '
                          
                          
                            ENGINE
                          
                          
                            '
                          
                          : 
                          
                            '
                          
                          
                            django.db.backends.mysql
                          
                          
                            '
                          
                          
                            ,
        
                          
                          
                            '
                          
                          
                            NAME
                          
                          
                            '
                          
                          : 
                          
                            '
                          
                          
                            mysql_test_db1
                          
                          
                            '
                          
                          
                            ,
        
                          
                          
                            '
                          
                          
                            USER
                          
                          
                            '
                          
                          : 
                          
                            '
                          
                          
                            root
                          
                          
                            '
                          
                          
                            ,
        
                          
                          
                            '
                          
                          
                            PASSWORD
                          
                          
                            '
                          
                          : 
                          
                            '
                          
                          
                            Se7eN521
                          
                          
                            '
                          
                          
                            ,
        
                          
                          
                            '
                          
                          
                            HOST
                          
                          
                            '
                          
                          : 
                          
                            '
                          
                          
                            127.0.0.1
                          
                          
                            '
                          
                          
                            ,
        
                          
                          
                            '
                          
                          
                            PORT
                          
                          
                            '
                          
                          : 
                          
                            '
                          
                          
                            3306
                          
                          
                            '
                          
                          
                            
    },
    
                          
                          
                            '
                          
                          
                            db2
                          
                          
                            '
                          
                          
                            : {
        
                          
                          
                            '
                          
                          
                            ENGINE
                          
                          
                            '
                          
                          : 
                          
                            '
                          
                          
                            django.db.backends.mysql
                          
                          
                            '
                          
                          
                            ,
        
                          
                          
                            '
                          
                          
                            NAME
                          
                          
                            '
                          
                          : 
                          
                            '
                          
                          
                            mysql_test_db2
                          
                          
                            '
                          
                          
                            ,
        
                          
                          
                            '
                          
                          
                            USER
                          
                          
                            '
                          
                          : 
                          
                            '
                          
                          
                            root
                          
                          
                            '
                          
                          
                            ,
        
                          
                          
                            '
                          
                          
                            PASSWORD
                          
                          
                            '
                          
                          : 
                          
                            '
                          
                          
                            Se7eN521
                          
                          
                            '
                          
                          
                            ,
        
                          
                          
                            '
                          
                          
                            HOST
                          
                          
                            '
                          
                          : 
                          
                            '
                          
                          
                            127.0.0.1
                          
                          
                            '
                          
                          
                            ,
        
                          
                          
                            '
                          
                          
                            PORT
                          
                          
                            '
                          
                          : 
                          
                            '
                          
                          
                            3306
                          
                          
                            '
                          
                          
                            
    }
}
                          
                        

3、实现思路

  1. 多个应用对应多个数据库和一个应用对应多个数据库
    1. 情况一:项目有多个 应用app 且需要使用到多个数据库
    2. 情况二:项目只有一个应用app, 且但需要使用到多个数据库,
  2. 这两种情况的实现思路其实都是一样的,都是为每个数据库创建一个应用,即这个应用只对接一个数据库,如果这个应用不需要写任何业务逻辑的代码,也需要创建一个空的应用,主要是用来做数据库迁移的
  3. 核心思想就是:一个model类对应一个数据库,通过数据库路由和model定义时指定的all_label来实现。

4、案例实现

  第一步:创建需要的 应用app,并且在 INSTALLED_APPS 中引用

    其中db1_app这个应用主要是用来对接数据库db1的 。

    其中db2_app这个应用主要是用来对接数据库db2的 。

    其中test_app这个应用主要用来实现业务逻辑的 。

                  。

  第二步:创建 应用app 和 数据库之间的映射关系

    在settings.py 文件夹中设置 DATABASE_APPS_MAPPING 的字典,里面主要是配置 应用app 和数据库的对应关系 。

                          DATABASE_APPS_MAPPING =
                          
                             {
    
                          
                          
                            "
                          
                          
                            db1_app
                          
                          
                            "
                          
                          : 
                          
                            "
                          
                          
                            db1
                          
                          
                            "
                          
                          ,   
                          
                            #
                          
                          
                             db1_app 对应 db1 数据库
                          
                          
                            "
                          
                          
                            db2_app
                          
                          
                            "
                          
                          : 
                          
                            "
                          
                          
                            db2
                          
                          
                            "
                          
                          
                            #
                          
                          
                             db2_app 对应 db2 数据库
                          
                          
}
                        

  第三步:创建数据库路由

    在项目的主文件夹即 settings.py 的同目录下创建一个 database_router.py 文件,该文件的作用就是给不同应用app 配置不同的数据库.

                          
                            #
                          
                          
                             _*_ coding:utf-8 _*_
                          
                          
                            
#
                          
                          
                             @Time : 2023/4/20 5:37 下午
                          
                          
                            from
                          
                           django.conf 
                          
                            import
                          
                          
                             settings

DATABASE_MAPPING 
                          
                          =
                          
                             settings.DATABASE_APPS_MAPPING

                          
                          
                            print
                          
                          (
                          
                            '
                          
                          
                            DATABASE_MAPPING = {}
                          
                          
                            '
                          
                          
                            .format(DATABASE_MAPPING))


                          
                          
                            class
                          
                          
                             DatabaseAppsRouter(object):

    
                          
                          
                            #
                          
                          
                             设置 应用app 读取时数据库的设置
                          
                          
                            def
                          
                           db_for_read(self, model, **
                          
                            hints)
                          
                          
                            if
                          
                           model._meta.app_label 
                          
                            in
                          
                          
                             DATABASE_MAPPING:
            
                          
                          
                            return
                          
                          
                             DATABASE_MAPPING[model._meta.app_label]
        
                          
                          
                            return
                          
                          
                             None

    
                          
                          
                            def
                          
                           db_for_write(self, model, **
                          
                            hints):
        
                          
                          
                            if
                          
                           model._meta.app_label 
                          
                            in
                          
                          
                             DATABASE_MAPPING:
            
                          
                          
                            return
                          
                          
                             DATABASE_MAPPING[model._meta.app_label]
        
                          
                          
                            return
                          
                          
                             None

    
                          
                          
                            def
                          
                           allow_relation(self, obj1, obj2, **
                          
                            hints):
        db_obj1 
                          
                          =
                          
                             DATABASE_MAPPING.get(obj1._meta.app_label)
        db_obj2 
                          
                          =
                          
                             DATABASE_MAPPING.get(obj2._meta.app_label)
        
                          
                          
                            if
                          
                           db_obj1 
                          
                            and
                          
                          
                             db_obj2:
            
                          
                          
                            if
                          
                           db_obj1 ==
                          
                             db_obj2:
                
                          
                          
                            return
                          
                          
                             True
            
                          
                          
                            else
                          
                          
                            :
                
                          
                          
                            return
                          
                          
                             False
        
                          
                          
                            return
                          
                          
                             None

    
                          
                          
                            def
                          
                           allow_migrate(self, db, app_label, model_name=None, **
                          
                            hints):
        
                          
                          
                            """
                          
                          
                            
        Make sure that apps only appear in the related database.
        根据app_label的值只在相应的数据库中创建一个表,如果删除该def或
        不指定过滤条件,则一个Model会在每个数据库里都创建一个表。
        
                          
                          
                            """
                          
                          
                            if
                          
                           db 
                          
                            in
                          
                          
                             DATABASE_MAPPING.values():
                          
                          
                            return
                          
                           DATABASE_MAPPING.get(app_label) ==
                          
                             db
        
                          
                          
                            elif
                          
                           app_label 
                          
                            in
                          
                          
                             DATABASE_MAPPING:
            
                          
                          
                            return
                          
                          
                             False
        
                          
                          
                            return
                          
                           None
                        

  第四步:在setting.py中配置 DATABASE_ROUTERS 指定自由路由文件:

                          
                            #
                          
                          
                            test_django为项目名,database_router为路由文件名,DatabaseAppsRouter为路由中创建的类名
                          
                          
DATABASE_ROUTERS = [
                          
                            '
                          
                          
                            django_db_demo.database_router.DatabaseAppsRouter
                          
                          
                            '
                          
                          ]
                        

  第五步:创建model类

    说明:model 可以根据需要卸载任何一个应用app的model.py文件中,也可以分散写在多个应用的model.py中,这个根据自己的需要即可,但是如何推荐一定要在model类的Meta中指定app_label。不然会全部将表创建到default数据库中 。

                          
                            from
                          
                           django.db 
                          
                            import
                          
                          
                             models


                          
                          
                            class
                          
                          
                             SqliteModel(models.Model):
    
                          
                          
                            """
                          
                          
                            帐号和用户关联
                          
                          
                            """
                          
                          
                            

    sqlite_name 
                          
                          = models.CharField(max_length=20
                          
                            )
    
                          
                          
                            class
                          
                          
                             Meta:
        
                          
                          
                            #
                          
                          
                             当前这个 SqliteModel 定义的数据库的表将会创建在test_app 对应的default 数据库中
                          
                          
        app_label = 
                          
                            "
                          
                          
                            test_app
                          
                          
                            "
                          
                          
                            #
                          
                          
                             当有多个数据库链接的时候,要通过app_label 来区分这个model对应那个数据库
                          
                          
                            class
                          
                          
                             Db1Model(models.Model):
    
                          
                          
                            """
                          
                          
                            帐号和用户关联
                          
                          
                            """
                          
                          
                            

    db1_name 
                          
                          = models.CharField(max_length=20
                          
                            )
    
                          
                          
                            class
                          
                          
                             Meta:
        
                          
                          
                            #
                          
                          
                             当前这个Db1Model 定义的数据库的表将会创建在 db1_app 对应的 db1 数据库中
                          
                          
        app_label = 
                          
                            "
                          
                          
                            db1_app
                          
                          
                            "
                          
                          
                            #
                          
                          
                             当有多个数据库链接的时候,要通过app_label 来区分这个model对应那个数据库
                          
                          
                            class
                          
                          
                             Db2Model(models.Model):
    
                          
                          
                            """
                          
                          
                            帐号和用户关联
                          
                          
                            """
                          
                          
                            

    db2_name 
                          
                          = models.CharField(max_length=20
                          
                            )
    
                          
                          
                            class
                          
                          
                             Meta:
        
                          
                          
                            #
                          
                          
                             当前这个Db2Model 定义的数据库的表将会创建在 db2_app 对应的 db1 数据库中
                          
                          
        app_label = 
                          
                            "
                          
                          
                            db2_app
                          
                          
                            "
                          
                          
                            #
                          
                          
                             当有多个数据库链接的时候,要通过app_label 来区分这个model对应那个数据库
                          
                        

  第六步:数据迁移

                          
                            python3 manage.py makemigrations  
python3 manage.py migrate 
                          
                          --database=default   
                          
                            #
                          
                          
                             当有多个数据库,需要迁移多次
                          
                          
python3 manage.py migrate --database=
                          
                            db1
python3 manage.py migrate 
                          
                          --database=db2 
                        

  第七步:查看迁移:

    model对应的表,分别迁移到不同的数据库成功,剩下的增删改查的就正常引入model对象即可,这样就实现了,不同的model对象,对应不用数据库的表.

第五步:总结

  1. 创建多个数据库连接设置
  2. 创建多个数据与应用app的映射关系
  3. 创建数据库路由
  4. 创建model类的时候置指明app_label,即这个model是属于那个app,从而觉得迁移到那个数据库

最后此篇关于django使用多个数据库实现的文章就讲到这里了,如果你想了解更多关于django使用多个数据库实现的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。

32 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com