当前位置:Gxlcms > 数据库问题 > Django配置数据库读写分离

Django配置数据库读写分离

时间:2021-07-01 10:21:17 帮助过:5人阅读

: { ‘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‘), }, }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

创建models并执行数据库迁移

这里我简单创建一张产品表

from django.db import models


class Products(models.Model):
    """产品表"""
    prod_name = models.CharField(max_length=30)
    prod_price = models.DecimalField(max_digits=6, decimal_places=2)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

创建完成后,执行数据库迁移操作:

python manage.py makemigrations  # 在migrations文件夹下生成记录,迁移前检查
python manage.py migrate  # 创建表
  • 1
  • 2

在migrations文件夹下生成记录,并在迁移前检查是否有问题,默认值检查defualt数据库,但是可以在后面的数据库路由类(Router)中通过allow_migrate()方法来指定是否检查其它的数据库。

其实第二步迁移默认有参数python manage.py migrate --database default ,在默认数据库上创建表。因此完成以上迁移后,执行python manage.py --database db2,再迁移一次,就可以在db2上创建相同的表。这样在项目根目录下,就有了两个表结构一样的数据库,分别是db.sqlite3和db2.sqlite3。

读写分离

手动读写分离

在使用数据库时,通过.using(db_name)来手动指定要使用的数据库

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)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

自动读写分离

通过配置数据库路由,来自动实现,这样就不需要每次读写都手动指定数据库了。数据库路由中提供了四个方法。这里这里主要用其中的两个: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‘
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
配置Router

settings.py中指定DATABASE_ROUTERS

DATABASE_ROUTERS = [‘myrouter.Router‘,]  
  • 1

可以指定多个数据库路由,比如对于读操作,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‘
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

分库分表

在大型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‘
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

 

更多请参考官网

Django配置数据库读写分离

标签:function   port   processor   char   目的   sqlite3   参数   multi   using   

人气教程排行