这一篇笔记介绍一下 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。
下面这个操作尽管是可行的,然而为了对立治理,还是不举荐这么操作。
本文首发于自己微信公众号:Django 笔记。
原文链接:Django 笔记三十七之多数据库操作 (补充版)
如果想获取更多相干文章,可扫码关注浏览: