配置数据库读写分离,前提条件是要做好数据库层面的读写分离和数据同步。
① 配置数据库,以 sqlite 为例
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
},
'slave': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': os.path.join(BASE_DIR, 'db2.sqlite3'),
},
}
② 数据库迁移
python manage.py migrate 默认使用 defalut 的数据配置,完整的写法为:python manage.py migrate --database defalut,同样的迁移完默认的数据库后,也要迁移从数据库 python manage.py migrate --database slave
③ 读写分离
方式一:可以使用手动的方式指定数据库的读写,通过一个方法 .using("数据库")
models.xxx.objects.using("slave").first()
my_object.save(using="slave") 可以指定存储的模型
from django.shortcuts import HttpResponse
from . import models
#指定写的数据库
def write(request):
models.Goods.objects.using('default').create(name='熊猫公仔', price=12.99)
return HttpResponse('写入成功')
# 指定读的数据库
def read(request):
obj = models.Goods.objects.filter(id=1).using('slave').first()
return HttpResponse(obj.name)
方式二:自动读写分离
通过配置数据库路由,来自动实现,这样就不需要每次读写都手动指定数据库了。数据库路由中提供了四个方法(db_for_read、db_for_write、allow_relation、allow_migrate)。这里主要用其中的两个:def db_for_read() 决定读操作的数据库,def db_for_write() 决定写操作的数据库。
④ 定义 Router 类
新建 db_router.py 脚本,定义 Router 类:
class MasterSlaveDBRouter(object):
"""读写分离路由"""
def db_for_read(self, model, **hints):
"""读"""
return "slave"
def db_for_write(self, model, **hints):
"""写"""
return "default"
def allow_relation(self, obj1, obj2, **hints):
"""允许关联查询"""
return True
⑤ 配置 Router
settings.py 中指定 DATABASE_ROUTERS
# 读写分离路由器
DATABASE_ROUTERS = ["utils.db_router.MasterSlaveDBRouter"]
⑥ 分库分表
在大型 web 项目中,常常会创建多个 app 来处理不同的业务,如果希望实现 app 之间的数据库分离,比如 app01 走数据库 db1,app02 走数据库 db2
class Router:
def db_for_read(self, model, **hints):
if model._meta.app_label == 'app01':
return 'db1'
if model._meta.app_label == 'app02':
return 'db2'
def db_for_write(self, model, **hints):
if model._meta.app_label == 'app01':
return 'db1'
if model._meta.app_label == 'app02':