django orm 读写分离,分库分app

1,读写分离

第一步:在settings下面配置

DATABASES = {
    'default': {
    'ENGINE': 'django.db.backends.mysql',
    'NAME': 'blog',
    'USER':'root',
    'PASSWORD':'123456',
    'HOST':'127.0.0.1',
    'PORT':'3306',
},
    'appinfo': {
    'ENGINE': 'django.db.backends.mysql',
    'NAME': 'db2',
    'USER': 'root',
    'PASSWORD': '123456',
    'HOST': '127.0.0.1',
    'PORT': '3306',
}
}

第二步、数据库迁移。 python manage.py migrate 默认使用default的数据配置,

完整的写法为: python manage.py migrate --database default ,同样的迁移完默认的数据库后,

也要迁移从数据库  python manage.py migrate --database db2

 

第三步、读写分离

第一种:用using()指定哪个数据库的使用
from django.shortcuts import HttpResponse
from . import models

#指定写的数据库 
def write(request):
    models.Products.objects.using('default').create(prod_name='熊猫公仔', prod_price=12.99)
    return HttpResponse('写入成功')

# 指定读的数据库
def read(request):
    obj = models.Products.objects.filter(id=1).using('db2').first()
    return HttpResponse(obj.prod_name)

方式二:自动读写分离
通过配置数据库路由,来自动实现,这样就不需要每次读写都手动指定数据库了。
数据库路由中提供了四个方法(db_for_read、db_for_write、allow_relation、allow_migrate)。
这里主要用其中的两个:def db_for_read()决定读操作的数据库,def db_for_write()决定写操作的数据库。

定义Router类
新建myrouter.py(名字只要和后面的配置对应上就行),定义Router类:
class Router:  #名字可以随便改
    def db_for_read(self, model, **hints):
        return 'db2'

    def db_for_write(self, model, **hints):
        return 'default'

配置Router

settings.py中指定DATABASE_ROUTERS


DATABASE_ROUTERS = ['myrouter.Router',] 
可以指定多个数据库路由,比如对于读操作,Django将会循环所有路由中的db_for_read()方法,直到其中一个有返回值,然后使用这个数据库进行当前操作。
一主多从方案

网站的读的性能通常更重要,因此,可以多配置几个数据库,并在读取时,随机选取,比如:

class Router:
    def db_for_read(self, model, **hints):
        """
        读取时随机选择一个数据库
        """
        import random
        return random.choice(['db2', 'db3', 'db4'])

    def db_for_write(self, model, **hints):
        """
        写入时选择主库
        """
        return 'default'

 

2,分app分库 

在大型web项目中,常常会创建多个app来处理不同的业务,如果希望实现app之间的数据库分离,比如app01走数据库db1,app02走另外数据库

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':
            return 'db2'

 

posted @ 2018-12-18 16:23  forjie  阅读(504)  评论(0编辑  收藏  举报