Django的数据库读写分离
1、首先是配置数据库
在settings.py
文件中增加多个数据库的配置:
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
},
'db2': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': os.path.join(BASE_DIR, 'db2.sqlite3'), # 指定数据库名
}
}
使用mysql
的配置:
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'HOST': '127.0.0.1',
'PORT': 3306,
'USER': 'user',
'PASSWORD': 'pd',
'NAME': 'db_read'
},
'db2': {
'ENGINE': 'django.db.backends.mysql',
'HOST': '127.0.0.1',
'PORT': 8306,
'USER': 'root',
'PASSWORD': 'pd',
'NAME': 'db_write'
}
}
2、执行数据库迁移
python manage.py migrate -- database db2 # 将default库中的表结构同步到db2
执行完上面的指令之后,你就会发现,db2这个库里面就有了我们的表
3、看看读写分离的情况下,django怎么玩
- 手动读写分离
在视图函数中,通过objects.using("库名") 指定使用哪个库
from django.shortcuts import HttpResponse
from . import models
def write(request):
models.Products.objects.using('default').create(name='大猿', age=12)
return HttpResponse('写入成功')
def read(request):
obj = models.Products.objects.using('db2').filter(id=1).first()
return HttpResponse(obj.name)
- 自动读写分离
重写创建一个py文件,这里我们创建一个router.py
文件
class Router:
# 读操作用default库,就return这个库名字符串
def db_for_read(self,model,**kwargs): # db_for_read固定写法,读操作自动匹配 # db_for_write固定写法,写操作自动匹配
return 'default'
# 读操作用db2库,就return这个库名字符串
def db_for_write(self,model,**kwargs): # db_for_write固定写法,写操作自动匹配
return 'db2'
还需要在settings.py
文件中进行配置:
DATABASE_ROUTERS = ['app01.router.Router',]
#写上面这个类的路径,我的是在app01应用文件夹下面的router.py文件中了
设置自动之后就不需要在视图的逻辑函数中操作库时使用using
def dbtest(request):
data = []
# 向db2数据库中写入数据
models.Class.objects.create(name='大猿',age=18)
# 从db1中读取数据
data = models.Class.objects.all()
return render(request,'dbtest.html',{'data':data})
4、一主多从方案
一主多从的时候,也就是从多个数据库中读取的时候,我们可以这样操作:还是创建一个文件写入下边的函数
import random
class Router:
def db_for_read(self, model, **kwargs):
return random.choices(['db1', 'db2', 'db3'])
#多个库读的时候,可以简单的写个随机选择
def db_for_write(self, model, **kwargs):
return 'db'
在settings.py
文件的配置和上边的一样:
DATABASE_ROUTERS = ['app01.router.Router',]
#写上面这个类的路径,我的是在app01应用文件夹下面的router.py文件中了
5、分库分表
当我们需要让不同的app操作不同的数据库时,比如app01
操作数据库db1
,app02
操作数据库db2
,我们应该如何去做,还是创建单独的文件,写法如下:
class Router:
def db_for_read(self, model, **kwargs):
if model._meta.app_label == 'app01':
return 'db1'
if model._meta.app_label == 'app02':
return 'db2'
def db_for_write(self, model, **kwargs):
if model._meta.app_label == 'app01':
return 'db1'
if model._meta.app_label == 'app02':
return 'db2'
# model._meta.app_label 获取当前函数所在app的app名称
# 如果是类,需要将类名加上
# model.UserInfo._meta.app_label 获取该类所在app的app名称
在settings.py
文件的配置:
DATABASE_ROUTERS = ['app01.router.Router',]
#写上面这个类的路径,我的是在app01应用文件夹下面的router.py文件中了