django数据库读写分离
目录
django之多数据库
一、多数据库-读写分离
由于一个django项目可能为了提高性能,会设置多个数据库,所以我们可以使用官方文档去学习如何设置
模型和数据库 - 多数据库 - 《Django v4.0 中文文档》 - 书栈网 · BookStack
1.在settings中配置数据库
DATABASES = {
# pg数据库
'default': {
'ENGINE': 'django.db.backends.postgresql',
'NAME': 'Test_DB',
'USER': 'postgres',
'PASSWORD': '123456',
'HOST': '127.0.0.7',
'PORT': 5432
},
# mysql数据库
'users': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'test_mysql',
'USER': 'root',
'PASSWORD': '123456',
'HOST':'127.0.0.7',
'PORT':3306
}
}
2.在app应用下的models中编写
class User(models.Model):
name = models.CharField(max_length=32)
age = models.IntegerField()
3.数据库迁移命令
#这个时候,因为现在是多个数据库,所以可以针对不同的数据库进行迁移
# 默认数据库 default - postgresql - shell
python manage.py makemigrations
python manage.py migrate
# users数据库 - mysql - shell
python manage.py migrate --database=users
4.编写分库方法
1. 方法1 - 使用using
from django.shortcuts import render,HttpResponse
from app01 import models
# Create your views here.
def index(request):
# 方式一
# 读数据 - users -msyql
res = models.User.objects.using('users').all().first()
# 写数据 - default -postgresql
models.User.objects.create(name=res.name,age=res.age)
return HttpResponse('index')
2. 方法2 - 编写类
# from django.db.models.options import Options -- 查询字段
class DatabaseRouter(object):
def db_for_read(self, model, **hints):
print(model._meta.app_label) # app01 有了这个可以分app判断 - 写逻辑
print(model._meta.model_name) # user 有着这里可以table判断 - 写逻辑
return 'users'
def db_for_write(self, model, **hints):
print(model._meta.app_label) # app01
print(model._meta.app_label) # user
return 'default'
3. 在settings中注册
# 配置数据库
DATABASE_ROUTERS = ['utils.database_selector.DatabaseRouter']
from django.shortcuts import render,HttpResponse
from app01 import models
# Create your views here.
def index(request):
# 方式一 - using
# 读数据 - users -msyql
# res = models.User.objects.using('users').all().first()
# 写数据 - default -postgresql
# models.User.objects.create(name=res.name,age=res.age)
# 方式二 - 类
res2 = models.User.objects.all().first()
print(res2)
models.User.objects.create(name=res2.name, age=res2.age)
return HttpResponse('index')
二、分库-app划分
1. 事前准备
首先,将数据库中的表删除
其次,将migrations 下的日志信息删除
最后,创建第二个app 为 app02
2. 在两个app应用中创建不同表
app01
# app01
from django.db import models
# Create your models here.
class UserPg(models.Model):
name = models.CharField(max_length=32)
age = models.IntegerField()
app02
# app02
from django.db import models
# Create your models here.
class UserMysql(models.Model):
name = models.CharField(max_length=32)
age = models.IntegerField()
3. 数据迁移 - 分库(app<---->数据库)
# 数据迁移日志
python manage.py makemigrations
# app01 下 迁移到 default - postgresql 数据库
python manage.py migrate app01 --database=default
# app02 下 迁移到 users - mysql 数据库
python manage.py migrate app02 --database=users
4. 注意事项
1.app 分库后,直接操作会报数据找不到
2.app分库后,需要使用 多数据库 - 读写分离的两种方式去配置
from django.shortcuts import render,HttpResponse
def index(request):
# 方式一
# 读数据 - users -msyql
# res = models.User.objects.using('users').all().first()
# 写数据 - default -postgresql
# models.User.objects.create(name=res.name,age=res.age)
# 方式二 - 类
# res2 = models.User.objects.all().first()
# print(res2)
# models.User.objects.create(name=res2.name, age=res2.age)
# 方式三 - app分库
from app01 import models as m1
from app02 import models as m2
res3 = m1.UserPg.objects.all()
print(res3)
res4 = m2.UserMysql.objects.all()
print(res4)
return HttpResponse('index')
5. 具体解决
# from django.db.models.options import Options -- 查询字段
class DatabaseRouter(object):
def db_for_read(self, model, **hints):
if model._meta.app_label == 'app01':
return 'default'
if model._meta.app_label == 'app02':
return 'users'
def db_for_write(self, model, **hints):
if model._meta.app_label == 'app01':
return 'default'
if model._meta.app_label == 'app02':
return 'users'
三、分库-单app
(同一app中,不同表放在不同库中)**
1. 编写类 - allow_migrate
class DatabaseRouter(object):
def db_for_read(self, model, **hints):
if model._meta.app_label == 'app02':
return 'default'
if model._meta.app_label == 'app03':
return 'users'
def db_for_write(self, model, **hints):
if model._meta.app_label == 'app02':
return 'default'
if model._meta.app_label == 'app03':
return 'users'
def allow_migrate(self, db, app_label, model_name=None, **hints):
if db == 'default':
if model_name in ['UserInfoPg']:
return True # 返回true 执行数据迁移命令时 生成到数据库中
else:
return False # 返回False 执行数据迁移命令时 不生成到数据库中
if db == 'users':
if model_name in ['UserInfoMysql']:
return True # 返回true 执行数据迁移命令时
else:
return False
2. 数据迁移
# 数据迁移日志
python manage.py makemigrations
# app01 下 迁移到 default - postgresql 数据库
python manage.py migrate app01 --database=default
# app02 下 迁移到 users - mysql 数据库
python manage.py migrate app02 --database=users
总结
1.分库 - 读写分离 - 多app - 单app
# settings 中配置
# DATABASE_ROUTERS = ['path.to.AuthRouter', 'path.to.PrimaryReplicaRouter']
class DatabaseRouter(object):
"""
A router to control all database operations on models in the
auth and contenttypes applications.
"""
route_app_labels = {'auth', 'contenttypes'}
def db_for_read(self, model, **hints):
"""
Attempts to read auth and contenttypes models go to auth_db.
"""
if model._meta.app_label in self.route_app_labels:
return 'auth_db'
return None
def db_for_write(self, model, **hints):
"""
Attempts to write auth and contenttypes models go to auth_db.
"""
if model._meta.app_label in self.route_app_labels:
return 'auth_db'
return None
def allow_relation(self, obj1, obj2, **hints):
"""
Allow relations if a model in the auth or contenttypes apps is
involved.
"""
if (
obj1._meta.app_label in self.route_app_labels or
obj2._meta.app_label in self.route_app_labels
):
return True
return None
def allow_migrate(self, db, app_label, model_name=None, **hints):
"""
Make sure the auth and contenttypes apps only appear in the
'auth_db' database.
"""
if app_label in self.route_app_labels:
return db == 'auth_db'
return None
2.注意事项
首先,表之间有关联的,应该在同一个库中
其次,分库可以根据需要,把关联的表分在同一个app中
然后,多数据库可以根据业务将不同的app下不同表分在不同库中,需要编写一个类。
最后,read / write 是库的orm操作 , migrate 是 数据迁移操作。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· 从HTTP原因短语缺失研究HTTP/2和HTTP/3的设计差异
· 三行代码完成国际化适配,妙~啊~