本文首發(fā)于公眾號(hào):Hunter后端
原文鏈接:Django筆記三十七之多數(shù)據(jù)庫(kù)操作(補(bǔ)充版)
這一篇筆記介紹一下 Django 里使用多數(shù)據(jù)庫(kù)操作。
在第二十二篇筆記中只介紹了多數(shù)據(jù)庫(kù)的定義、同步命令和使用方式,這一篇筆記作為補(bǔ)充詳細(xì)介紹如何對(duì) Django 系統(tǒng)的多個(gè)數(shù)據(jù)庫(kù)進(jìn)行針對(duì)的建表同步操作。
以下是本篇筆記目錄:
- DATABASES 定義
- application創(chuàng)建和設(shè)置
- migration 和 migrate 操作
- 幾個(gè)注意的點(diǎn)
1、DATABASES 定義
這里還是復(fù)用之前的 Django 系統(tǒng),這里我們額外建立兩個(gè)數(shù)據(jù)庫(kù)連接,之前的 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,
},
}
數(shù)據(jù)庫(kù)里的連接名稱分別是 user 和 other。
注意,這里我們使用的是不同的數(shù)據(jù)庫(kù) DATABASE,分別是 db_1 和 db_2,他們可以在一個(gè)地址的 MySQL 里,也可以在不同地址。
2、application創(chuàng)建和設(shè)置
接下來(lái)我們以 application 為整體來(lái)指定 model 對(duì)數(shù)據(jù)庫(kù)進(jìn)行操作。
上面這句話這里釋義一下,就是說(shuō)針對(duì)多個(gè)數(shù)據(jù)庫(kù),我們這里默認(rèn)使用整個(gè) application 下的 model 表與之對(duì)應(yīng),比如說(shuō) new_user 這個(gè) app 下的 model 的 migration 操作都寫入 DATABASE 下 user 對(duì)應(yīng)的數(shù)據(jù)庫(kù)。
當(dāng)然,這個(gè)操作過(guò)程我們還需要在 settings.py 中定義一個(gè)映射 DATABASE_APPS_MAPPING,這個(gè)我們后面再說(shuō)。
創(chuàng)建application
首先,我們分別創(chuàng)建兩個(gè) application,一個(gè) application 名為 new_user,另一個(gè)名為 other_info,使用下面的命令創(chuàng)建:
python3 manage.py startapp new_user
python3 manage.py startapp other_info
然后在系統(tǒng)的根目錄會(huì)出現(xiàn)這兩個(gè)文件夾。
然后在 settings.py 中注冊(cè)這兩個(gè) app:
# hunter/settings.py
INSTALLED_APPS = [
...
'new_user.apps.NewUserConfig',
'other_info.apps.OtherInfoConfig',
...
]
application與數(shù)據(jù)庫(kù)的對(duì)應(yīng)設(shè)置
然后設(shè)置 application 與 DATABASE 的對(duì)應(yīng)關(guān)系:
DATABASE_APPS_MAPPING = {
"new_user": "user",
"other_info": "other",
}
在這里的這個(gè)映射關(guān)系的 key 是我們的 application 的名稱,value 則是 settings.py 中 DATABASES 對(duì)應(yīng)的數(shù)據(jù)庫(kù)的 key。
比如這里我們將 new_user 這個(gè) app 指定到了 user 數(shù)據(jù)庫(kù)。
創(chuàng)建 model
接下來(lái)我們分別在兩個(gè) application 下創(chuàng)建對(duì)應(yīng)的 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"
在這兩個(gè) model 里,我手動(dòng)給其添加了 app_label 字段,值為各自所在 application 下的名,表示這個(gè) model 是從屬于 app_label 這個(gè) application 下。
其實(shí)對(duì)于每個(gè) model,meta 信息下都會(huì)有這個(gè)字段,默認(rèn)值為該 model 所處的 application 的名稱,這里為了顯示對(duì)比,我額外標(biāo)記了出來(lái)。
查看 app_label 的方式為:
from new_user.models import NewUser
NewUser._meta.app_label
# new_user
而在前面的 settings.py 里我們?cè)O(shè)置了 DATABASE_APPS_MAPPING 映射
DATABASE_APPS_MAPPING = {
"new_user": "user",
"other_info": "other",
}
所以這里的 NewUser model 使用的就是 user 這個(gè)數(shù)據(jù)庫(kù)。
接下來(lái)我們可以進(jìn)行 migration 操作來(lái)測(cè)試將表結(jié)構(gòu)寫入 user 數(shù)據(jù)庫(kù)。
3、migration 和 migrate 操作
接下來(lái)我們創(chuàng)建 migration 文件:
python3 manage.py makemigrations new_user
python3 manage.py makemigrations other_info
然后會(huì)在 new_user 和 other_info 下分別創(chuàng)建對(duì)應(yīng)的 migration 文件。
接下來(lái)進(jìn)行 migrate 的時(shí)候需要指定 database 參數(shù),也就是我們前面 settings.py 里的 DATABASES 的對(duì)應(yīng)的 key:
python3 manage.py migrate new_user --database=user
python3 manage.py migrate other_info --database=other
根據(jù) settings.py 里 DATABASE_APPS_MAPPING 里的映射關(guān)系,--database 對(duì)應(yīng)的參數(shù)就是相應(yīng)的數(shù)據(jù)庫(kù)。
執(zhí)行完上面的命令之后,在兩個(gè)對(duì)應(yīng)的數(shù)據(jù)庫(kù)里就會(huì)創(chuàng)建 django_migrations 表和 model 對(duì)應(yīng)的表。
創(chuàng)建 django_migrations 表是因?yàn)槊總€(gè) database 也需要記錄各自的 migration 遷移記錄。
至此,我們就將 application 下的 model 和 database 對(duì)應(yīng)了起來(lái)。
4、幾個(gè)注意的點(diǎn)
數(shù)據(jù)的增刪改查
前面我們將 model 和 database 對(duì)應(yīng)了起來(lái)之后,在操作對(duì)應(yīng)的 model 的時(shí)候還是需要 using() 來(lái)指定操作的 database:
from new_user.models import NewUser
NewUser.objects.using("user").create(id=1)
default數(shù)據(jù)庫(kù)
在這篇筆記里,我們另外設(shè)置了兩個(gè)數(shù)據(jù)庫(kù)用于對(duì)應(yīng)新建的 application,且在 DATABASE_APPS_MAPPING 中設(shè)置了 application 到 database 的映射,那么沒有設(shè)置映射關(guān)系的 application 下的 model 其實(shí)就還是默認(rèn)屬于 default 數(shù)據(jù)庫(kù)的。
比如我們之前創(chuàng)建的 blog 這個(gè) application,就相當(dāng)于是:
DATABASE_APPS_MAPPING = {
"blog": "default",
"new_user": "user",
"other_info": "other",
}
不過(guò)因?yàn)槭悄J(rèn)設(shè)置,所以為了方便我們沒有顯式的設(shè)置出來(lái)。
并且,對(duì)于多個(gè) application 是可以對(duì)應(yīng)同一個(gè)數(shù)據(jù)庫(kù)鏈接的,比如我們默認(rèn)的 default,沒有設(shè)置的 application 都對(duì)應(yīng)的是 default 的數(shù)據(jù)庫(kù)鏈接。
假設(shè)我們又創(chuàng)建了一個(gè)名為 article 的 app,也想要對(duì)應(yīng) other 數(shù)據(jù)庫(kù),可以這樣操作:
DATABASE_APPS_MAPPING = {
"blog": "default",
"new_user": "user",
"other_info": "other",
"article": "other",
}
某 app 下設(shè)置其他 app 的 model
這個(gè)操作是否可以呢?
可以,假設(shè)我們?cè)?new_user 下創(chuàng)建一個(gè) model,但是設(shè)置的是 other_info 的 app_label:
# new_user/models.py
class OtherInfoInNewUser(models.Model):
pass
class Meta:
app_label = "other_info"
然后我們對(duì) new_user 這個(gè) app 執(zhí)行下面的操作是檢測(cè)不到有新 migration 的
python3 manage.py makemigrations new_user
因?yàn)楫?dāng)我們 makemigrations 指定 app 名稱的時(shí)候,系統(tǒng)會(huì)去檢測(cè)這個(gè) app 下是否有屬于這個(gè) app 的新的 model 變化,而我們?cè)O(shè)置 OtherInfoInNewUser 這個(gè) model 卻從屬于 other_info,所以是檢測(cè)不到變化的。
只有當(dāng)我們執(zhí)行:
python3 manage.py makemigrations other_info
這個(gè)操作的時(shí)候,系統(tǒng)才會(huì)檢測(cè)到 app_label='other_info' 的 model 的變化,然后創(chuàng)建新的 migration。
上面這個(gè)操作雖然是可行的,但是為了統(tǒng)一管理,還是不推薦這么操作。文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-435706.html
如果想獲取更多后端相關(guān)文章,可掃碼關(guān)注閱讀:文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-435706.html
到了這里,關(guān)于Django筆記三十七之多數(shù)據(jù)庫(kù)操作(補(bǔ)充版)的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!