zoukankan      html  css  js  c++  java
  • 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
  • 相关阅读:
    适配器模式
    自己DIY word2010脚注和尾注没有的格式
    Linux单网卡,双IP,双网关配置,并搭建squid proxy上网
    about using gnuplot
    ReadDirectoryChangesW 函数 流沙
    Jquery easyui 异步树 流沙
    Overlapped I/O 学习 流沙
    jQuery.get(url,[data],[callback]) 流沙
    MsgWaitForMultipleObjectsEx用法 流沙
    Oracle smon_scn_time 表 说明
  • 原文地址:https://www.cnblogs.com/Gaimo/p/12177485.html
Copyright © 2011-2022 走看看