Django的数据库读写分离

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文件的配置:

扫描二维码关注公众号,回复: 8418124 查看本文章
DATABASE_ROUTERS = ['app01.router.Router',] 
#写上面这个类的路径,我的是在app01应用文件夹下面的router.py文件中了

猜你喜欢

转载自www.cnblogs.com/zhufanyu/p/12149562.html