Django实现多数据库连接后,接下来讲述如何在开发过程中使用多数据库实现数据的读写操作。
如果您还不知道如何创建多数据库的连接,请看上一篇文章——多数据库的连接
以下例子都以上一篇文章为例
一、在项目应用index和user的models.py里分别定义模型City和PersonInfo:
# index的models.py
from django.db import models
class City(models.Model):
name = models.CharField(max_length=50)
def __str__(self):
return self.name
class Meta:
# 设置模型所属的App,在数据库db1里生成数据表
# 若不设置app_label,则默认为当前文件所在的App
apple_label = 'index'
# 自定义数据表名称
db_table = 'city'
# 定义数据表在Admin后台的显示名称
verbose_name = '城市信息表'
# user的models.py
from django.db import models
class PersonInfo(models.Model):
name = models.CharField(max_length=50)
age = models.CharField(max_length=100)
live = models.CharField(max_length=100)
def __str__(self):
return self.name
class Meta:
# 设置模型所属的App,在数据库db2里生成数据表
# 若不设置app_label,则默认为当前文件所在的App
apple_label = 'user'
# 自定义数据表名称
db_table = 'personinfo'
# 定义数据表在Admin后台的显示名称
verbose_name = '个人信息表'
两个类型之间存在一对多关系,模型PersonInfo的字段live代表个人的居住城市,但是字段live不能使用ForeignKey关联City,因为他们两者隶属于不同的数据库,所以无法建立数据表关系。
二、数据库迁移
City和PersonInfo的Meta属性设置了app_label,这是将模型归属到某个项目应用,由于配置文件settings.py设置了DATABASE_APPS_MAPPING属性,将每个项目应用的模型指定了所属的数据库,因此能确定模型City和PersonInfo在哪个数据库中创建数据表。
在pycharm的terminal下输入并执行迁移指令makemigrations和migrate。
makemigrations指令在项目应用的migrations文件夹里创建0001_initial.py文件,但执行migrate指令时,django不会在数据库db1和db2里创建模型City和PersonInf的数据表,只在Sqlite3数据库里创建django内置功能的数据表。若要为模型City和PersonInfo创建相应的数据表,则需要在migtate指令中设置参数:
# 在数据库default(db.sqlite3)中创建内置功能的数据表
python manage.py migrate
# 在数据库db1(Mysql的indexdb)中创建数据表
python manage.py migrate --dtabase=db1
# 在数据库db2(Mysql的userdb)中创建数据表
python manage.py migrate --dtabase=db2
三、数据的读写
无论django连接单个还是多个数据库,数据的读写方式都是相同的,但是多表查询必须保证两张数据表建立在同一个数据库,否则只能执行多次单表查询。
以以上模型为例,PersonInfo的字段live代表个人的居住城市,他与City可以构建外键关系,但两者隶属于不同的数据库。若查询居住在广州的人员信息,则只能分别对两个模型进行单独查询:
>>> from user.models import PersonInfo
>>> from index.models import City
# 创建数据
>>> City.objects.create(name='广州')
<City: 广州>
>>> d=dict(name='Lucy',age=20,live='1')
>>> PersonInfo.objects.create(**d)
<PersonInfo: Lucy>
# 查询居住在广州的人员信息
# 在模型City中查询“广州”的数据对象c
>>> c=City.objects.filter(name='广州').first()
# 从数据对象c获取主键id,作为模型PersonInfo的查询条件
>>> p=PersonInfo.objects.filter(live=str(c.id))
>>> p
<QuerySet [<PersonInfo: Lucy>]>