Django连接数据库并实现读写分离过程解析

下面我来详细讲解“Django连接数据库并实现读写分离过程解析”的完整攻略。

什么是读写分离

读写分离指的是在一个数据库中,将读写操作分别放在不同的数据库实例上进行。因为读和写的负载不同,如果两者在同一台数据库实例上执行,那么会很容易出现读写冲突,导致系统压力过大,从而影响系统的稳定性和可用性。因此我们要将读写操作分离,以便更好地优化数据库的性能。

Django连接数据库的方式

Django连接数据库的方式有两种:一种是使用Django自带的ORM,另一种是使用原生的SQL语句。

使用Django自带的ORM连接数据库

# settings.py中定义数据库连接信息
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',  
        'NAME': 'db',                            # 数据库名
        'USER': 'user',                          # 用户名
        'PASSWORD': 'password',                  # 密码
        'HOST': '127.0.0.1',                      # 数据库地址
        'PORT': '3306',                          # 数据库端口
    },
}

# models.py定义数据库表
from django.db import models

class Book(models.Model):
    name = models.CharField(max_length=100)
    author = models.CharField(max_length=100)
    date_published = models.DateField()

# views.py中对数据库进行操作
from .models import Book

def create_book(request):
    book = Book(name='Django Book', author='John', date_published='2021-01-01')
    book.save()

这是使用Django自带的ORM连接数据库的方式。我们首先在settings.py文件中定义数据库连接信息,然后在models.py文件中定义数据库表。在views.py文件中可以通过import语句导入相关的models文件,以对数据库进行操作。具体的操作方式可以参考官方文档。

使用原生的SQL语句连接数据库

# settings.py中定义数据库连接信息
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'db',
        'USER': 'user',
        'PASSWORD': 'password',
        'HOST': '127.0.0.1',
        'PORT': '3306',
    },
}

# views.py中使用原生SQL语句进行操作
from django.db import connections

def create_book(request):
    with connections['default'].cursor() as cursor:
        query = "INSERT INTO app_book (name, author, date_published) VALUES (%s, %s, %s)"
        cursor.execute(query, ('Django Book', 'John', '2021-01-01'))

这是使用原生的SQL语句连接数据库的方式。我们同样需要在settings.py文件中定义数据库连接信息,然后在views.py文件中通过django.db.connections获取默认数据库连接,并在with语句中定义游标,以执行SQL语句对数据库进行操作。

Django实现读写分离的方式

Django实现读写分离的方式有两种:一种是通过使用第三方库django-mysql-replication实现,另一种是通过自定义数据库路由实现。

通过使用django-mysql-replication实现

django-mysql-replication是一个第三方库,可以通过它来实现Django的读写分离。它基于MySQL的binlog日志,实时复制数据库,并同步到多个从库上,从而实现读写分离。

安装django-mysql-replication

通过pip命令安装:

pip install django-mysql-replication

配置django-mysql-replication

在settings.py中添加以下配置:

DATABASE_ROUTERS = ['mysql_router.MasterSlaveRouter']
DJANGO_MYSQL_REPLICATION = {
    'MASTER': {
        'host': '127.0.0.1',
        'port': '3306',
        'user': 'user',
        'password': 'password',
        'server_id': '1',
        'binlog_stream': 'MASTER',
        'blocking': False
    },
    'SLAVES': [
        {
            'host': '127.0.0.1',
            'port': '3307',
            'user': 'user',
            'password': 'password',
            'server_id': '2',
            'blocking': False
        },
        {
            'host': '127.0.0.1',
            'port': '3308',
            'user': 'user',
            'password': 'password',
            'server_id': '3',
            'blocking': False
        },
    ],
}

这里我们定义了2个从库,分别监听了3307和3308端口。

自定义数据库路由

在app目录下创建mysql_router.py文件,定义MasterSlaveRouter类,继承自django.db.routers.BaseRouter,重载db_for_read和db_for_write方法。

class MasterSlaveRouter:
    def db_for_read(self, model, **hints):
        return 'slave_db'

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

这里我们定义了一种读写分离的方式,读操作走从库,写操作走主库。

控制数据库的读写操作

在操作数据库时,可以通过read_from指定读操作应该从哪个数据库中读取数据。

from django.db import connections

# 从数据库中随机读取数据
def read_book(request):
    with connections['slave_db'].cursor() as cursor:
        cursor.execute("SELECT id, name, author, date_published FROM app_book ORDER BY RAND() LIMIT 1")
        row = cursor.fetchone()
        book = {
            "id": row[0],
            "name": row[1],
            "author": row[2],
            "date_published": row[3]
        }
        return JsonResponse(book)

# 写数据到主库
def create_book(request):
    with connections['master_db'].cursor() as cursor:
        query = "INSERT INTO app_book (name, author, date_published) VALUES (%s, %s, %s)"
        cursor.execute(query, ('Django Book', 'John', '2021-01-01'))
        return HttpResponse('Create book success')

这里我们可以通过read_from指定从哪个数据库中进行读操作,同时在create_book函数中也可以指定只从主库中写入数据。

通过自定义数据库路由实现

上面我们介绍了使用第三方库来实现读写分离的方式,而现在我们来介绍如何通过自定义数据库路由来实现读写分离。

自定义数据库路由

我们在app目录下的mysql_router.py文件中自定义MasterSlaveRouter类:

class MasterSlaveRouter:
    def db_for_read(self, model, **hints):
        return 'slave_db'

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

    def allow_relation(self, obj1, obj2, **hints):
        db_obj1 = getattr(obj1, '_state').db or 'default'
        db_obj2 = getattr(obj2, '_state').db or 'default'
        if db_obj1 == 'master_db' or db_obj2 == 'master_db':
            return False
        return True

    def allow_migrate(self, db, app_label, model_name=None, **hints):
        if db == 'master_db':
            return app_label == 'app'
        elif app_label == 'app':
            return False
        return None

这里我们定义了一种读写分离的方式,读操作走从库,写操作走主库,并且定义了allow_relation和allow_migrate方法,分别用于限制关联表和进行数据迁移的操作。

配置多个数据库连接信息

在settings.py中定义多个数据库连接信息:

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'db',
        'USER': 'user',
        'PASSWORD': 'password',
        'HOST': '127.0.0.1',
        'PORT': '3306',
    },
    'master_db': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'db',
        'USER': 'user',
        'PASSWORD': 'password',
        'HOST': '127.0.0.1',
        'PORT': '3306',
    },
    'slave_db': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'db',
        'USER': 'user',
        'PASSWORD': 'password',
        'HOST': '127.0.0.1',
        'PORT': '3307',
    },
}

这里我们定义了3个不同的数据库连接信息,用于连接主库、从库以及默认库。

控制数据库的读写操作

在操作数据库时,可以通过using指定读写操作应该从哪个数据库中进行。

from app.models import Book

# 从数据库中随机读取数据
def read_book(request):
    book = Book.objects.using('slave_db').order_by('?').first()
    return JsonResponse({
        "id": book.id,
        "name": book.name,
        "author": book.author,
        "date_published": book.date_published,
    })

# 写数据到主库
def create_book(request):
    book = Book(name='Django Book', author='John', date_published='2021-01-01')
    book.save(using='master_db')
    return HttpResponse('Create book success')

这里我们可以通过using指定从哪个数据库中进行读写操作。

以上就是关于Django连接数据库并实现读写分离的完整攻略,包含了两种实现方式以及相关示例。希望您能够掌握其中的要点,顺利进行项目的开发。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Django连接数据库并实现读写分离过程解析 - Python技术站

(0)
上一篇 2023年5月16日
下一篇 2023年5月16日

相关文章

  • Python+django实现文件下载

    下面是关于Python+django实现文件下载的完整攻略以及两条示例说明。 什么是Django? Django是一个Python Web框架,采用了MVC的软件架构模式,是一个全功能的高级Web框架。Django的官方网站是djangoproject.com。 Django实现文件下载的方法 在Django中,可以通过编写视图函数实现文件的下载。 示例1:…

    Django 2023年5月16日
    00
  • django使用uwsgi启动

    django默认是wsgi启动,不能利用到多核执行效率很低,通过uwsgi来解决这个问题。   python虚拟环境安装配置: https://www.cnblogs.com/zezhou/p/14509198.html python虚拟环境使用操作: https://www.cnblogs.com/zezhou/p/14509203.html   安装uw…

    Django 2023年4月11日
    00
  • django之定义统一返回数据格式与GET/POST装饰器

    1. 为了返回给网页前端的格式统一,定义一个通用的插件类,返回统一格式数据 # enconding:utf-8 “”” 定义一个插件类, “”” from django.http import JsonResponse,HttpResponse # 自定义状态码 class HttpCode(object): # 正常登陆 ok = 200 # 参数错误 p…

    Django 2023年4月13日
    00
  • Django 入门项目案例开发(中)

      关注微信公众号:FocusBI 查看更多文章;加QQ群:808774277 获取学习资料和一起探讨问题。   昨天已经描述了如何搭建Django的开发环境,今天描述业务流程,具体我们要实现一个什么样的业务;   以下的业务都是假设的(网上书店   页面做的low):   1.用户注册及登录业务:     这是一个网上书店阅读平台,用户注册后可以阅读书籍;…

    Django 2023年4月11日
    00
  • python web框架【补充】cookie和session(Django)

    一、cookie和session的介绍 cookie不属于http协议范围,由于http协议无法保持状态,但实际情况,我们却又需要“保持状态”,因此cookie就是在这样一个场景下诞生。 cookie的工作原理是:由服务器产生内容,浏览器收到请求后保存在本地;当浏览器再次访问时,浏览器会自动带上cookie,这样服务器就能通过cookie的内容来判断这个是“…

    Django 2023年4月12日
    00
  • django框架学习:二十五.django xadmin管理后台

    前面学习了django自带的admin后台管理感觉页面不美观,网上的大神优化了一版后台管理xadmin,并且开源了,在github开源下载到源码。 django 2.1.2 xadmin 2.0 python 3.6 xadmin安装 xadmin在github的源码地址https://github.com/sshwsfc/xadmin,可以用pip安装也可…

    2023年4月10日
    00
  • Python Django框架模板渲染功能示例

    Python Django是一个快速开发web应用程序的框架。其中,模板渲染是Django的一个核心功能,它通过将业务逻辑和视图分离,使得前端页面与后端逻辑解耦,为开发人员提供了构建高质量Web应用程序的强有力的方式。下面我们详细介绍Python Django框架模板渲染功能示例。 示例一:创建Django项目 首先,你需要创建一个Django项目。假设我们…

    Django 2023年5月16日
    00
  • Django设置/获取/删除session

    # 设置sessiondef setSession(request): request.session[‘username’] = ‘ruan’ request.session[‘isLogin’] = True return HttpResponse(‘OK’)# 获取session def GetSession(request): isLogin = r…

    Django 2023年4月13日
    00
合作推广
合作推广
分享本页
返回顶部