django数据库读写分离

django数据库读写分离

1. 配置数据库

settings.py文件中
用SQLite:
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
    },
    'salve': {
        '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': 'passwd',
        'NAME': 'db_read'
    },
    'slave': {
        'ENGINE': 'django.db.backends.mysql',
        'HOST': '127.0.0.1',
        'PORT': 8306,
        'USER': 'root',
        'PASSWORD': 'mysqlpwd',
        'NAME': 'db_write'
    }
}
2.创建models并执行数据库迁移(略)
3.操作读写分离

- 手动读写分离

------views.py视图文件中------
object.using(‘default’) 这里指定用哪个库,
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.filter(id=1).using('salve').first()
    return HttpResponse(obj.name)

- 自动读写分离

通过配置数据库路由,来自动实现。
新建router.py文件
class Router:
    def db_for_read(self, model, **hints):
    '''
    db_for_read固定写法,读操作自动匹配
    '''
        return 'slave'
    def db_for_write(self, model, **hints):
    '''
    db_for_write固定写法,写操作自动匹配
    '''
        return 'default'

配置router

------settings.py------文件中
DATABASE_ROUTERS = ['router.Router',]  

4.一主多从方案

新建router.py文件
class Router:
    def db_for_read(self, model, **hints):
        """
        读取时随机选择一个数据库
        """
        import random
        return random.choice(['salve1', 'slave2', 'slave3'])
    def db_for_write(self, model, **hints):
        """
        写入时选择主库
        """
        return 'default'

配置router

------settings.py------文件中
DATABASE_ROUTERS = ['router.Router',]  

5.分库分表

新建router.py文件
app之间的数据库分离,比如app01走数据库salve1,app02走数据库slave2
class Router:
    def db_for_read(self, model, **hints):
        if model._meta.app_label == 'app01':
            return 'salve1'
        if model._meta.app_label == 'app02':
            return 'slave2'
    def db_for_write(self, model, **hints):
       if model._meta.app_label == 'app01':
            return 'slave1'
       if model._meta.app_label == 'app02':
            return 'slave2'

配置router

------settings.py------文件中
DATABASE_ROUTERS = ['router.Router',]  

 配置注意事项:

python manage.py makemigraions

python manage.py migrate app名称 --databse=配置文件数据名称的别名

手动操作:
    models.UserType.objects.using('db1').create(title='普通用户')
    result = models.UserType.objects.all().using('default')
    
自动操作:
    class Router1:
        def db_for_read(self, model, **hints):
            """
            Attempts to read auth models go to auth_db.
            """
            return 'db1'

        def db_for_write(self, model, **hints):
            """
            Attempts to write auth models go to auth_db.
            """
            return 'default'

    配置:
        DATABASES = {
            'default': {
                'ENGINE': 'django.db.backends.sqlite3',
                'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
            },
            'db1': {
                'ENGINE': 'django.db.backends.sqlite3',
                'NAME': os.path.join(BASE_DIR, 'db1.sqlite3'),
            },
        }
        DATABASE_ROUTERS = ['db_router.Router1',]
        
    使用:
        models.UserType.objects.create(title='VVIP')

        result = models.UserType.objects.all()
        print(result)
                            
    补充:粒度更细
        class Router1:
            def db_for_read(self, model, **hints):
                """
                Attempts to read auth models go to auth_db.
                """
                if model._meta.model_name == 'usertype':
                    return 'db1'
                else:
                    return 'default'

            def db_for_write(self, model, **hints):
                """
                Attempts to write auth models go to auth_db.
                """
                return 'default'
问题: 
    app01中的表在default数据库创建
    app02中的表在db1数据库创建
    
    # 第一步:
        python manage.py makemigraions 
    
    # 第二步:
        app01中的表在default数据库创建
        python manage.py migrate app01 --database=default
    
    # 第三步:
        app02中的表在db1数据库创建
        python manage.py migrate app02 --database=db1
        
    # 手动操作:
        m1.UserType.objects.using('default').create(title='VVIP')
        m2.Users.objects.using('db1').create(name='VVIP',email='xxx')
    # 自动操作:
        配置: 
            class Router1:
                def db_for_read(self, model, **hints):
                    """
                    Attempts to read auth models go to auth_db.
                    """
                    if model._meta.app_label == 'app01':
                        return 'default'
                    else:
                        return 'db1'

                def db_for_write(self, model, **hints):
                    """
                    Attempts to write auth models go to auth_db.
                    """
                    if model._meta.app_label == 'app01':
                        return 'default'
                    else:
                        return 'db1'

            DATABASE_ROUTERS = ['db_router.Router1',]
        
        使用: 
            m1.UserType.objects.using('default').create(title='VVIP')
            m2.Users.objects.using('db1').create(name='VVIP',email='xxx')
其他:
    数据库迁移时进行约束:
        class Router1:
            def allow_migrate(self, db, app_label, model_name=None, **hints):
                """
                All non-auth models end up in this pool.
                """
                if db=='db1' and app_label == 'app02':
                    return True
                elif db == 'default' and app_label == 'app01':
                    return True
                else:
                    return False
                
                # 如果返回None,那么表示交给后续的router,如果后续没有router,则相当于返回True
                
            def db_for_read(self, model, **hints):
                """
                Attempts to read auth models go to auth_db.
                """
                if model._meta.app_label == 'app01':
                    return 'default'
                else:
                    return 'db1'

            def db_for_write(self, model, **hints):
                """
                Attempts to write auth models go to auth_db.
                """
                if model._meta.app_label == 'app01':
                    return 'default'
                else:
                    return 'db1'



docker run -it -p 8000:8000 --name=mydemo -v /home/test/:/usr/lqz my_django_test python /usr/lqz/djangotest2/manage.py runserver 0.0.0.0:8000


docker run -it -p 8000:8000 --name=mydemo_lqz_django -v /home/test/:/usr/lqz lqz_django_v1 python /usr/lqz/djangotest2/manage.py runserver 0.0.0.0:8000

猜你喜欢

转载自www.cnblogs.com/Gaimo/p/12177485.html