• 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文件中了
    
  • 相关阅读:
    Entity Framework 学习中级篇2—存储过程(上)(转)
    PB TreeView 属性,事件详解(转)
    java面试宝典
    Entity Framework 学习初级篇5ObjectQuery查询及方法(转)
    关于安卓中国移动定制机GPS定位问题解决办法
    Asp.net中优化页面小技巧—让搜索引擎更容易找到你的页面!
    服务器SQl2000和SQl2005版本不同带来一系列问题解决方案
    Asp.net中小技巧—服务器端Web控件与客户端Html控件交互
    Asp.net中利用ExecuteNonQuery()执行存储过程返回1解决方案
    Asp.net中DropDownlist中无法触发后台事件解决方案
  • 原文地址:https://www.cnblogs.com/zhufanyu/p/12149562.html
Copyright © 2020-2023  润新知