zoukankan      html  css  js  c++  java
  • 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文件的配置:

    DATABASE_ROUTERS = ['app01.router.Router',] 
    #写上面这个类的路径,我的是在app01应用文件夹下面的router.py文件中了
    
  • 相关阅读:
    5月做题计划(数据结构)
    SRM 545 DIV2
    6月做题计划(递归与分治)
    POJ 3121 The SetStack Computer
    struts2初步学习路线
    my97datepicker日历展示出现中文乱码的问题
    tomcat请求数据的编码设置
    STRUT2传递参数中文乱码解决方法
    js mine 类型javascripttext/javascript,application/javascript, and appliation/xjavascript
    eclipse内存设置参数
  • 原文地址:https://www.cnblogs.com/zhufanyu/p/12149562.html
Copyright © 2011-2022 走看看