一、說明:
在開發 Django 專案的時候,很多時候都是使用一個資料庫,即 settings 中只有 default 資料庫,但是有一些專案確實也需要使用多個資料庫,這樣的專案,在資料庫配置和使用的時候,就比較麻煩一點,
二、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' } }
三、實作思路
- 多個應用對應多個資料庫和一個應用對應多個資料庫
- 情況一:專案有多個 應用app 且需要使用到多個資料庫
- 情況二:專案只有一個應用app, 且但需要使用到多個資料庫,
- 這兩種情況的實作思路其實都是一樣的,都是為每個資料庫創建一個應用,即這個應用只對接一個資料庫,如果這個應用不需要寫任何業務邏輯的代碼,也需要創建一個空的應用,主要是用來做資料庫遷移的
- 核心思想就是:一個model類對應一個資料庫,通過資料庫路由和model定義時指定的all_label來實作,
四、案例實作
第一步:創建需要的 應用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物件,對應不用資料庫的表,

第五步:總結
- 創建多個資料庫連接設定
- 創建多個資料與應用app的映射關系
- 創建資料庫路由
- 創建model類的時候置指明app_label,即這個model是屬于那個app,從而覺得遷移到那個資料庫
侯哥語錄:我曾經是一個職業教育者,現在是一個自由開發者,我希望我的分享可以和更多人一起進步,分享一段我喜歡的話給大家:"我所理解的自由不是想干什么就干什么,而是想不干什么就不干什么,當你還沒有能力說不得時候,就努力讓自己變得強大,擁有說不得權利,"
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/550758.html
標籤:Python
上一篇:【K哥爬蟲普法】微信公眾號爬蟲構成不正當競爭,爬蟲er面對金山,如何避免濫用爬蟲?
下一篇:返回列表
