本文首發於公眾號:Hunter後端 原文鏈接:Django筆記三十七之多資料庫操作(補充版) 這一篇筆記介紹一下 Django 里使用多資料庫操作。 在第二十二篇筆記中只介紹了多資料庫的定義、同步命令和使用方式,這一篇筆記作為補充詳細介紹如何對 Django 系統的多個資料庫進行針對的建表同步操作。 ...
本文首發於公眾號:Hunter後端
這一篇筆記介紹一下 Django 里使用多資料庫操作。
在第二十二篇筆記中只介紹了多資料庫的定義、同步命令和使用方式,這一篇筆記作為補充詳細介紹如何對 Django 系統的多個資料庫進行針對的建表同步操作。
以下是本篇筆記目錄:
- DATABASES 定義
- application創建和設置
- migration 和 migrate 操作
- 幾個註意的點
1、DATABASES 定義
這裡還是復用之前的 Django 系統,這裡我們額外建立兩個資料庫連接,之前的 default 還是不變:
# hunter/settings.py
DATABASES = {
'default': {
...
},
'user': {
'ENGINE': "django.db.backends.mysql",
'NAME': "db_1",
"USER": "root",
"PASSWORD": "123456",
"HOST": "192.168.1.10",
"PORT": 3306,
},
'other': {
'ENGINE': "django.db.backends.mysql",
'NAME': "db_2",
"USER": "root",
"PASSWORD": "123456",
"HOST": "192.168.1.11",
"PORT": 3306,
},
}
資料庫里的連接名稱分別是 user 和 other。
註意,這裡我們使用的是不同的資料庫 DATABASE,分別是 db_1 和 db_2,他們可以在一個地址的 MySQL 里,也可以在不同地址。
2、application創建和設置
接下來我們以 application 為整體來指定 model 對資料庫進行操作。
上面這句話這裡釋義一下,就是說針對多個資料庫,我們這裡預設使用整個 application 下的 model 表與之對應,比如說 new_user 這個 app 下的 model 的 migration 操作都寫入 DATABASE 下 user 對應的資料庫。
當然,這個操作過程我們還需要在 settings.py 中定義一個映射 DATABASE_APPS_MAPPING,這個我們後面再說。
創建application
首先,我們分別創建兩個 application,一個 application 名為 new_user,另一個名為 other_info,使用下麵的命令創建:
python3 manage.py startapp new_user
python3 manage.py startapp other_info
然後在系統的根目錄會出現這兩個文件夾。
然後在 settings.py 中註冊這兩個 app:
# hunter/settings.py
INSTALLED_APPS = [
...
'new_user.apps.NewUserConfig',
'other_info.apps.OtherInfoConfig',
...
]
application與資料庫的對應設置
然後設置 application 與 DATABASE 的對應關係:
DATABASE_APPS_MAPPING = {
"new_user": "user",
"other_info": "other",
}
在這裡的這個映射關係的 key 是我們的 application 的名稱,value 則是 settings.py 中 DATABASES 對應的資料庫的 key。
比如這裡我們將 new_user 這個 app 指定到了 user 資料庫。
創建 model
接下來我們分別在兩個 application 下創建對應的 model:
# new_user/models.py
from django.db import models
class NewUser(models.Model):
pass
class Meta:
app_label = "new_user"
# other_info/models.py
from django.db import models
class OtherInfo(models.Model):
pass
class Meta:
app_label = "other_info"
在這兩個 model 里,我手動給其添加了 app_label 欄位,值為各自所在 application 下的名,表示這個 model 是從屬於 app_label 這個 application 下。
其實對於每個 model,meta 信息下都會有這個欄位,預設值為該 model 所處的 application 的名稱,這裡為了顯示對比,我額外標記了出來。
查看 app_label 的方式為:
from new_user.models import NewUser
NewUser._meta.app_label
# new_user
而在前面的 settings.py 里我們設置了 DATABASE_APPS_MAPPING 映射
DATABASE_APPS_MAPPING = {
"new_user": "user",
"other_info": "other",
}
所以這裡的 NewUser model 使用的就是 user 這個資料庫。
接下來我們可以進行 migration 操作來測試將表結構寫入 user 資料庫。
3、migration 和 migrate 操作
接下來我們創建 migration 文件:
python3 manage.py makemigrations new_user
python3 manage.py makemigrations other_info
然後會在 new_user 和 other_info 下分別創建對應的 migration 文件。
接下來進行 migrate 的時候需要指定 database 參數,也就是我們前面 settings.py 里的 DATABASES 的對應的 key:
python3 manage.py migrate new_user --database=user
python3 manage.py migrate other_info --database=other
根據 settings.py 里 DATABASE_APPS_MAPPING 里的映射關係,--database 對應的參數就是相應的資料庫。
執行完上面的命令之後,在兩個對應的資料庫里就會創建 django_migrations 表和 model 對應的表。
創建 django_migrations 表是因為每個 database 也需要記錄各自的 migration 遷移記錄。
至此,我們就將 application 下的 model 和 database 對應了起來。
4、幾個註意的點
數據的增刪改查
前面我們將 model 和 database 對應了起來之後,在操作對應的 model 的時候還是需要 using() 來指定操作的 database:
from new_user.models import NewUser
NewUser.objects.using("user").create(id=1)
default資料庫
在這篇筆記里,我們另外設置了兩個資料庫用於對應新建的 application,且在 DATABASE_APPS_MAPPING 中設置了 application 到 database 的映射,那麼沒有設置映射關係的 application 下的 model 其實就還是預設屬於 default 資料庫的。
比如我們之前創建的 blog 這個 application,就相當於是:
DATABASE_APPS_MAPPING = {
"blog": "default",
"new_user": "user",
"other_info": "other",
}
不過因為是預設設置,所以為了方便我們沒有顯式的設置出來。
並且,對於多個 application 是可以對應同一個資料庫鏈接的,比如我們預設的 default,沒有設置的 application 都對應的是 default 的資料庫鏈接。
假設我們又創建了一個名為 article 的 app,也想要對應 other 資料庫,可以這樣操作:
DATABASE_APPS_MAPPING = {
"blog": "default",
"new_user": "user",
"other_info": "other",
"article": "other",
}
某 app 下設置其他 app 的 model
這個操作是否可以呢?
可以,假設我們在 new_user 下創建一個 model,但是設置的是 other_info 的 app_label:
# new_user/models.py
class OtherInfoInNewUser(models.Model):
pass
class Meta:
app_label = "other_info"
然後我們對 new_user 這個 app 執行下麵的操作是檢測不到有新 migration 的
python3 manage.py makemigrations new_user
因為當我們 makemigrations 指定 app 名稱的時候,系統會去檢測這個 app 下是否有屬於這個 app 的新的 model 變化,而我們設置 OtherInfoInNewUser 這個 model 卻從屬於 other_info,所以是檢測不到變化的。
只有當我們執行:
python3 manage.py makemigrations other_info
這個操作的時候,系統才會檢測到 app_label='other_info' 的 model 的變化,然後創建新的 migration。
上面這個操作雖然是可行的,但是為了統一管理,還是不推薦這麼操作。
如果想獲取更多後端相關文章,可掃碼關註閱讀: