GouHuang

导航

 

1.启动Mysql一主一从服务
Mysql的一主多从下,只有主库才能进行读写,从库只能读不能写
2.在setting.py,中首先配置多个数据库

DATABASES = {
    #默认数据库,配置多个mysql数据也是ok的,混用数据库也是ok的
    'default': {
            'ENGINE': 'django.db.backends.mysql',
            'NAME': 'crm',
            'USER': 'root',
            'PASSWORD': 'xxxx',
            'HOST': '127.0.0.1',
            'PORT': '3306', #(主数据库,所在端口)
        }

    #配置的第二个数据库,注意数据库名字不能相同
   'slave': {
              'ENGINE': 'django.db.backends.mysql',
              'NAME': 'crm',
              'USER': 'root',
              'PASSWORD': 'xxxx',
              'HOST': '127.0.0.1',
              'PORT': '3307', #(从数据库,所在端口)
          }
}

3. 进行数据库迁移

python manage.py makemigrations
python manage.py migrate 

在migrations文件夹下生成记录,并在迁移前检查是否有问题,默认值检查defualt数据库,但是可以在后面的数据库路由类(Router)中通过allow_migrate()方法来指定是否检查其它的数据库。
其实第二步迁移默认有参数python manage.py migrate --database default ,在默认数据库上创建表。
因为我采用的是Mysql的一主多从,迁移时候只需要迁移至主数据库就行了,也就是默认的default数据库,从数据库会会自动根据主数据库进行备份
4.怎么实现读写分离
方法一:手动

def dbtest(request):
    # 向default数据库中写入数据
    # models.Class.objects.using('default').create(name='xx')

    # 从slave中读取数据
    data = models.Class.objects.using('slave').all()
    # 更新时
    for i in data:
        i.name = 'xxxxxx'
        i.save(using='default') #更新时指定数据库
    return render(request,'dbtest.html',{'data':data})

方法二:自动
a.在应用文件夹中创建一个py文件(比如我写在app01目录下),名字随意,比如叫做router.py文件,写上下面的内容

class Router:
    # 读操作用default库,就return这个库名字符串
    def db_for_read(self,model,**kwargs): # 方法名必须叫这个,不可更改
        return 'default'

    def db_for_write(self,model,**kwargs):# 方法名必须叫这个,不可更改
        return 'db2'

b.然后在 settings.py 配置文件中做下面的配置

#写上面这个类的路径,我的是在app01应用文件夹下面的router.py文件中了
DATABASE_ROUTERS = ['app01.router.Router',] 

c.那么在逻辑的views.py文件中写的时候,就不需要using指定数据库了

def dbtest(request):
    # 向default数据库中写入数据
    # models.Class.objects.create(name='xx')

    # 从slave中读取数据
    data = models.Class.objects.all()
    # 更新时
    for i in data:
        i.name = 'xxxxxx'
        i.save() #更新时指定数据库
    return render(request,'dbtest.html',{'data':data})

c.如果有多个应用,Mysql也有多个从从复制,也可以根据不同的应用来选择不同的库进行读取

import random
class Router:
    # 读操作用default库,就return这个库名字符串
    def db_for_read(self,model,**kwargs):
        print(model)
        print(dir(model))# 其中有个_meta属性很有用
        a = model._meta.app_label #获取当前model对象所在的应用名称     
        m = model._meta.model_name  获取当前操作的model对象的表名,也可以根据表名来进行多数据库读的分配
        # 可以根据应用选择不用的库来进行读取
        if a == 'app01':
            return 'slave01'
        elif a == 'app02':
            return 'db2'
        return 'slave02' # 假定mysql 设置了不止一个从文件

    def db_for_write(self,model,**kwargs):

参考:
永远的超哥 https://www.cnblogs.com/clschao/articles/11804924.html
不知名的好人 http://t.zoukankan.com/hanbowen-p-9899569.html

posted on 2022-04-10 15:42  GouHuang  阅读(55)  评论(0编辑  收藏  举报