利用SQLAlchemy为Django配置数据库连接池的两种实现方案

小石头
小石头
发布时间:2026-10-12| 1人浏览过
原创

本文详细介绍如何在Django项目中引入SQLAlchemy构建数据库连接池,以解决高负载下频繁创建销毁连接的性能瓶颈。文章提供了两种修改Django源码的方法,重点解析了处理kwargs中字典类型导致的unhashable错误的关键代码修改,并附带了适用于Django 1.7与Python 2.7环境的配置示例。

通常情况下,Django框架在每次处理请求时都会建立新的数据库连接并在请求结束后释放。虽然这种机制在低负载场景下运行正常,但随着服务器并发请求量的增加,频繁地创建和销毁数据库连接会消耗大量系统资源,导致性能下降。为了解决这一问题,引入数据库连接池成为必要的优化手段。本文将以SQLAlchemy的连接池机制为例,展示如何实现Django数据库连接的持久化管理。

需要注意的是,实现连接池通常需要修改Django框架的底层代码,这属于对框架的侵入式修改,可能影响后续框架升级或维护。

方法 1

具体实现步骤如下:

首先,需要将Django源码中django/db/backends/mysql目录下的所有文件完整拷贝至项目内部的libs/mysql目录中,随后对该目录下的base.py文件进行修改。

另一种做法是将django/db/backends/mysql目录在django/db/backends/路径下复制一份,并重命名为mysql_pool文件夹。接着,将base.py文件中所有涉及mysql的import语句替换为mysql_pool。完成上述操作后,即可在项目的settings.py配置文件中直接指定'ENGINE':'django.db.backends.mysql_pool'来启用该后端。

找到

try: 
 import MySQLdb as Database
except ImportError as e: 
 from django.core.exceptions import ImproperlyConfigured 
 raise ImproperlyConfigured("Error loading MySQLdb module: %s" % e)

这段代码,在下面添加:

from sqlalchemy import pool
Database = pool.manage(Database[,recycle=DATABASE_WAIT_TIMEOUT-1])
#其中DATABASE_WAIT_TIMEOUT为你定义的连接超时时间,必须小于等于mysql里面的wait_timeout()

结果如下

try: 
 import MySQLdb as Database
except ImportError as e: 
 from django.core.exceptions import ImproperlyConfigured 
 raise ImproperlyConfigured("Error loading MySQLdb module: %s" % e)
from sqlalchemy import pool
Database = pool.manage(Database)

然后找到get_connection_params(self)函数代码:

def get_connection_params(self):
 kwargs = {
  'conv':django_conversions,
  'charset':utf8
  }
  ...

修改为:

def get_connection_params(self):
 kwargs = {
  'charset':utf8
  }
  ...

注意:如果不改变此处的kwargs,将会出现:TypeError:unhashable type:'dict' 的错误。

原样用kwargs传的话,sqlalchemy的pool会报unhashable错误,那是因为kwargs中有个key(conv)对应的value(django_conversions)是个字典,在pool中会把(key,value)组成元组作为新的key保存在pool中,但是因为value(django_conversions)是dict,不允许作为key的

在mysql里使用 show status 或 show processlist查看连接情况

方法 2

直接在settings.py同级目录下的init.py文件中添加如下代码

from django.conf import settings
from django.db.utils import load_backend
import sqlalchemy.pool as pool
import logging
pool_initialized=False

def init_pool():
  if not globals().get('pool_initialized', False):
   global pool_initialized
   pool_initialized = True
   try:
    backendname = settings.DATABASES['default']['ENGINE']
    backend = load_backend(backendname)

    #replace the database object with a proxy.
    backend.Database = pool.manage(backend.Database)

    backend.DatabaseError = backend.Database.DatabaseError
    backend.IntegrityError = backend.Database.IntegrityError
    logging.info("Connection Pool initialized")
   except:
    logging.exception("Connection Pool initialization error")

init_pool()

然后修改django/db/backends/mysql/base.py文件

找到get_connection_params(self)函数代码:

修改为:

def get_connection_params(self):
 kwargs = {
  'charset':utf8
  }
  ...

同理,不修改kwargs将会出现:TypeError:unhashable type:'dict' 的错误。

以上两种方法都要改变django的代码,有一定入侵性,第二种方法改变要小一点

django 1.7 python 2.7 sqlalchemy 1.0

这篇用sqlalchemy构建Django连接池的实例就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持本站。

免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。

Python 相关产品和应用

全部下载
Selenium

Selenium

4.51.0 · Windows

用于浏览器自动化和 Web 测试的 Python 工具。

scikit-learn

scikit-learn

1.9.1 · Windows

常用 Python 机器学习算法与模型评估工具库。

Black

Black

26.10.1 · Windows

强调一致性的 Python 自动代码格式化工具。

Ruff

Ruff

0.17.1 · macOS

由 Rust 编写的高速 Python 代码检查和格式化工具。

pytest

pytest

9.1.1 · Windows

简洁而强大的 Python 自动化测试框架。

FastAPI

FastAPI

0.146.0 · Windows

高性能 Python API 框架,支持类型提示和自动接口文档。

Flask

Flask

3.1.3 · Windows

轻量灵活的 Python Web 应用框架。

Django

Django

6.1.2 · Windows

成熟的 Python Web 框架,适合构建内容站点和业务系统。

Spyder

Spyder

6.1.7 · Windows

面向科学计算与数据分析的 Python 集成开发环境。

SciPy

SciPy

1.18.1 · Windows

面向科学、工程和技术计算的 Python 算法库。