zoukankan      html  css  js  c++  java
  • Django 连接多个数据库并实现读写分离

     Django 连接多个数据库并实现读写分离

      当一个项目当中有大量的数据的时候,你所有的 IO 操作都在一个数据库中操作,会造成项目的性能的降低。如果你能对项目中的数据进行读写分离的话,那么将大大提高你项目的性能。而 Django 自带的机制也对此提供了支持。我们可以简单的操作一下。(当然数据的同步还是需要运维同志的协助)

    修改配置文件

    Django 默认的是default, 我们按照它的格式直接添加一个新的配置:

    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'),
        }
    }

    当然,如果你不想使用默认的 sqlite3,想使用 mysql 还需要自己进行一下配置

    DATABASES = {
        'default': {
            'ENGINE': 'django.db.backends.mysql',
            'HOST': '127.0.0.1',  # 主服务器的运行ip
            'PORT': 3306,   # 主服务器的运行port
            'USER': 'django',  # 主服务器的用户名
            'PASSWORD': 'django',  # 主服务器的密码
            'NAME': 'djangobase'   #  数据表名
        },
        'slave': {
            'ENGINE': 'django.db.backends.mysql', 
            'HOST': '127.0.0.1',
            'PORT': 8306,
            'USER': 'django_slave',
            'PASSWORD': 'django_slave',
            'NAME': 'djangobase_slave'
        }
    }  

    在项目目录下的__init__文件中添加以下代码,将数据连接方式改为 pymysql

    import pymysql
     
    pymysql.install_as_MySQLdb()

    将数据配置修改完之后就可以在 models.py 文件当中创建表,接下里就可以进行数据库迁移了

    python manage.py makemigrations  # 在migrations文件夹下生成记录
     
    python manage.py migrate --database default  # 默认可以不写参数
     
    python manage.py migrate --database db2  # 在从库再迁移一次,就可以在上面建立相同的表

    手动读写分离

    在遇到数据库相关操作的话,需要手动指定要使用的相应数据库,不需要进行多余的配置,但是,当你数据的读写操作过于频繁的时候,这个方法就会略显繁琐。

    from django.shortcuts import render, HttpResponse
    from app001 import models
     
     
    # Create your views here.
     
     
    def write(request):
        models.User.objects.using('default').create(name='张三', pwd='123', phone=1234)
        return HttpResponse('写成功')
     
     
    def read(request):
        obj = models.User.objects.filter(id=1).using('db2').first()
        return HttpResponse('读成功')

    自动读写分离

      通过配置数据库路由,来自动实现读写分离,这样就不需要每次读写都手动指定数据库。

    在项目的 app 中创建 db_router.py 文件, 并在该文件中定义一个数据库路由类, 用来进行读写分离,这个类最多提供四个方法,分别是:db_for_readdb_for_writeallow_relationallow_migrate,以下只写了三个。

    定义数据库路由类

    class MasterSlaveDBRouter(object):
        """数据库主从读写分离路由"""
     
        def db_for_read(self, model, **hints):
            """读数据库"""
            return "slave"
     
        def db_for_write(self, model, **hints):
            """写数据库"""
            return "default"
     
        def allow_relation(self, obj1, obj2, **hints):
            """是否运行关联操作"""
            return True  

    配置 Router

    在 settings.py 中指定 DATABASE_ROUTERS

    DATABASE_ROUTERS = ["app001.db_router.MasterSlaveDBRouter"]

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

    一主多从数据库的使用

    # 一主多从 
    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'

    分库分表的使用

    # 分库分表 
    # app01 db1 app02 db2
    
    
    class Router: 
        #
        def db_for_read(self, model, **kwargs): 
            if model._meta.app_label == 'app01':
                 return 'db1 '
             elif model._meta.app_label == 'app02': 
                return 'db2' 
        #
        def db_for_write(self, model, **kwargs):
            if model._meta.app_label == 'app01': 
                    return 'db1 ' 
            elif model._meta.app_label == 'app02': 
                    return 'db2'                                    

     

  • 相关阅读:
    jsbeautifier + JScript.NET/JavaScript 编程实现 JavaScript、HTML、CSS 代码格式化脚本命令行工具 并集成到 EditPlus
    EasyTimer
    HttpTaskAsyncHandler IHttpAsyncHandler
    ConcurrentAsyncQueue 20120721
    HttpProxyHandler
    SocketAsyncDataHandler SocketAsyncEventArgs echo server
    DateTimeHelper R2
    managedwifi.codeplex.com
    最广泛报表数据源模型
    报表的发布
  • 原文地址:https://www.cnblogs.com/Gaimo/p/15431514.html
Copyright © 2011-2022 走看看