翼度科技»论坛 编程开发 python 查看内容

django使用多个数据库实现

7

主题

7

帖子

21

积分

新手上路

Rank: 1

积分
21
一、说明:

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

  2.1 默认只是用一个数据库时 DATABASES 的设置(以 SQLite 为例)
  1. DATABASES = {
  2.     'default': {
  3.         'ENGINE': 'django.db.backends.sqlite3',         
  4.         'NAME': 'db.sqlite3',
  5.     }
  6. }
复制代码
  2.2 Django 数据库支持的 ENGINE 类型



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

  2.3 设置了多个数据库后 settings 中的 DATABASES 的设置
  1. DATABASES = {
  2.     'default': {
  3.         'ENGINE': 'django.db.backends.sqlite3',
  4.         'NAME': 'db.sqlite3',
  5.     },
  6.     'db1': {
  7.         'ENGINE': 'django.db.backends.mysql',
  8.         'NAME': 'mysql_test_db1',
  9.         'USER': 'root',
  10.         'PASSWORD': 'Se7eN521',
  11.         'HOST': '127.0.0.1',
  12.         'PORT': '3306'
  13.     },
  14.     'db2': {
  15.         'ENGINE': 'django.db.backends.mysql',
  16.         'NAME': 'mysql_test_db2',
  17.         'USER': 'root',
  18.         'PASSWORD': 'Se7eN521',
  19.         'HOST': '127.0.0.1',
  20.         'PORT': '3306'
  21.     }
  22. }
复制代码
三、实现思路


  • 多个应用对应多个数据库和一个应用对应多个数据库

    • 情况一:项目有多个 应用app 且需要使用到多个数据库
    • 情况二:项目只有一个应用app, 且但需要使用到多个数据库,

  • 这两种情况的实现思路其实都是一样的,都是为每个数据库创建一个应用,即这个应用只对接一个数据库,如果这个应用不需要写任何业务逻辑的代码,也需要创建一个空的应用,主要是用来做数据库迁移的
  • 核心思想就是:一个model类对应一个数据库,通过数据库路由和model定义时指定的all_label来实现。
四、案例实现

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

    其中db1_app这个应用主要是用来对接数据库db1的
    其中db2_app这个应用主要是用来对接数据库db2的
    其中test_app这个应用主要用来实现业务逻辑的
                 

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

    在settings.py 文件夹中设置 DATABASE_APPS_MAPPING 的字典,里面主要是配置 应用app 和数据库的对应关系
  1. DATABASE_APPS_MAPPING = {
  2.     "db1_app": "db1",   # db1_app 对应 db1 数据库
  3.     "db2_app": "db2"    # db2_app 对应 db2 数据库
  4. }
复制代码
  第三步:创建数据库路由

    在项目的主文件夹即 settings.py 的同目录下创建一个 database_router.py 文件,该文件的作用就是给不同应用app 配置不同的数据库。
  1. # _*_ coding:utf-8 _*_
  2. # @Time : 2023/4/20 5:37 下午
  3. from django.conf import settings
  4. DATABASE_MAPPING = settings.DATABASE_APPS_MAPPING
  5. print('DATABASE_MAPPING = {}'.format(DATABASE_MAPPING))
  6. class DatabaseAppsRouter(object):
  7.     # 设置 应用app 读取时数据库的设置
  8.     def db_for_read(self, model, **hints)if model._meta.app_label in DATABASE_MAPPING:
  9.             return DATABASE_MAPPING[model._meta.app_label]
  10.         return None
  11.     def db_for_write(self, model, **hints):
  12.         if model._meta.app_label in DATABASE_MAPPING:
  13.             return DATABASE_MAPPING[model._meta.app_label]
  14.         return None
  15.     def allow_relation(self, obj1, obj2, **hints):
  16.         db_obj1 = DATABASE_MAPPING.get(obj1._meta.app_label)
  17.         db_obj2 = DATABASE_MAPPING.get(obj2._meta.app_label)
  18.         if db_obj1 and db_obj2:
  19.             if db_obj1 == db_obj2:
  20.                 return True
  21.             else:
  22.                 return False
  23.         return None
  24.     def allow_migrate(self, db, app_label, model_name=None, **hints):
  25.         """
  26.         Make sure that apps only appear in the related database.
  27.         根据app_label的值只在相应的数据库中创建一个表,如果删除该def或
  28.         不指定过滤条件,则一个Model会在每个数据库里都创建一个表。
  29.         """
  30.         if db in DATABASE_MAPPING.values():return DATABASE_MAPPING.get(app_label) == db
  31.         elif app_label in DATABASE_MAPPING:
  32.             return False
  33.         return None
复制代码
  第四步:在setting.py中配置 DATABASE_ROUTERS 指定自由路由文件:
  1. #test_django为项目名,database_router为路由文件名,DatabaseAppsRouter为路由中创建的类名
  2. DATABASE_ROUTERS = ['django_db_demo.database_router.DatabaseAppsRouter']
复制代码
  第五步:创建model类

    说明:model 可以根据需要卸载任何一个应用app的model.py文件中,也可以分散写在多个应用的model.py中,这个根据自己的需要即可,但是如何推荐一定要在model类的Meta中指定app_label。不然会全部将表创建到default数据库中
  1. from django.db import models
  2. class SqliteModel(models.Model):
  3.     """帐号和用户关联"""
  4.     sqlite_name = models.CharField(max_length=20)
  5.     class Meta:
  6.         # 当前这个 SqliteModel 定义的数据库的表将会创建在test_app 对应的default 数据库中
  7.         app_label = "test_app"      # 当有多个数据库链接的时候,要通过app_label 来区分这个model对应那个数据库
  8.    
  9. class Db1Model(models.Model):
  10.     """帐号和用户关联"""
  11.     db1_name = models.CharField(max_length=20)
  12.     class Meta:
  13.         # 当前这个Db1Model 定义的数据库的表将会创建在 db1_app 对应的 db1 数据库中
  14.         app_label = "db1_app"        # 当有多个数据库链接的时候,要通过app_label 来区分这个model对应那个数据库
  15.       
  16. class Db2Model(models.Model):
  17.     """帐号和用户关联"""
  18.     db2_name = models.CharField(max_length=20)
  19.     class Meta:
  20.         # 当前这个Db2Model 定义的数据库的表将会创建在 db2_app 对应的 db1 数据库中
  21.         app_label = "db2_app"       # 当有多个数据库链接的时候,要通过app_label 来区分这个model对应那个数据库
  22.       
复制代码
  
  第六步:数据迁移
  1. python3 manage.py makemigrations  
  2. python3 manage.py migrate --database=default   # 当有多个数据库,需要迁移多次
  3. python3 manage.py migrate --database=db1
  4. python3 manage.py migrate --database=db2
复制代码
  第七步:查看迁移:

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

第五步:总结


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

来源:https://www.cnblogs.com/Se7eN-HOU/p/17339885.html
免责声明:由于采集信息均来自互联网,如果侵犯了您的权益,请联系我们【E-Mail:cb@itdo.tech】 我们会及时删除侵权内容,谢谢合作!

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x

举报 回复 使用道具