django 数据库连接模块解析及简单长连接改造方法


Posted in Python onAugust 29, 2019

工作中纯服务端的项目用到了线程池和django的ORM部分。django 的数据库连接在每一个线程中开启一份,并在查询完毕后自动关闭连接。

线程池处理任务时,正常使用的连接中不会被关闭,但由于数据库端有最长连接时间的限制(默认为8小时),在超时后会发生InterfaceError: (0, '')(连接关闭后使用连接/游标)或Error(2006, 'MySQL server has gone away')(mysql 服务器主动关闭连接)这类错误,所以一般会在每个任务线程中调用django.db.connection.close()进行关闭操作。

但对于频繁进行数据库连接并操作数据库的业务,反复创建连接并不是好的选择,这种场景下可以考虑将连接改造为长连接。

1. django 代码的阅读笔记

django.db.__init__.py 
#对象:
connections = ConnectionHandler()
connection = DefaultConnectionProxy()
# 函数
# 重置查询记录缓存
def reset_queries(**kwargs):
 pass
# 关闭不可用或超时(如果有设置 CONN_MAX_AGE)连接
def close_old_connections(**kwargs):
 pass
# 信号
# 在请求开始或完成时自动调用相应处理函数
signals.request_started.connect(reset_queries)
signals.request_started.connect(close_old_connections)
signals.request_finished.connect(close_old_connections)

重点是connections和connection两个实例

connections 是 ConnectionHandler类

connections.all()会给出一个列表,里面的元素为DatabaseWrapper类

ConnectionHandler内置对象及连接管理:

def __init__():
 self._connections = local()

# 连接包装类里的连接是根据配置情况使用相应的连接
def __getitem__(self, alias):
 '''略'''
 db = self.databases[alias]
 backend = load_backend(db['ENGINE'])
 conn = backend.DatabaseWrapper(db, alias)
 setattr(self._connections, alias, conn)

# 返回所管理的数据库连接
# 管理方式:分数据库,线程管理连接 
def all(self):
 return [self[alias] for alias in self]

# 关闭所有数据库连接
def close_all(self):
 for alias in self:
  try:
   connection = getattr(self._connections, alias)
  except AttributeError:
   continue
  connection.close()

threading.local 是一个全局变量,local的属性是非线程共享的,也就是在每一个线程中都会有单独一个数据库连接实例创建,因为代理及包装的原因,该连接实例为对应backend里的连接(比如,pymysql.connections.Connection)。

在线程池的情况下,close_old_connections方法是不能将线程中的数据库连接关闭的。

connection是DefaultConnectionProxy类的实例,实际是DatabaseWrapper的实例 
(使用了pymysql库:import pymysql; pymysql.install_as_MySQLdb) 
DefaultConnectionProxy?>DatabaseWrapper?>pymysql.connections.Connection(根据connections的处理调用相应的数据库连接包) 
connection有几个关键方法和属性

connection.connection = '被包装的pymysql.connections.Connection实例`
connection.close_at = None if max_age is None else time.time() + max_age # 设置的连接关闭时间

connection.connect()# 获取连接
connection.cursor() # 获取游标
connection.close()# 关闭连接

2. 将数据库连接改造为长连接

max_age(CONN_MAX_AGE) 是可以在settings里面配置的。

由于多个服务共用一套配置, 所以考虑直接在程序里修改

全局变量

max_age = 7 * 3600

在线程内开始时做下判断:

if not db.connection.connection or db.connection.close_at < time.time():
 db.connection.close()
 db.connection.connect()
 db.connection.close_at = time.time() + max_age
 print "A new conn creates !"
else:
 print "Still old conn!"

这样每个线程池中的线程会循环执行任务并只使用同一个连接,并可以控制在自己需要的连接时长后更换连接。

针对线程池的情况,close_old_connections基本没啥用处, 可以跳过该处理

django.db.close_old_connections = lambda **kwargs : None

以上这篇django 数据库连接模块解析及简单长连接改造方法就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持三水点靠木。

Python 相关文章推荐
Python SQLAlchemy基本操作和常用技巧(包含大量实例,非常好)
May 06 Python
Python开发实例分享bt种子爬虫程序和种子解析
May 21 Python
python3调用R的示例代码
Feb 23 Python
Django框架视图函数设计示例
Jul 29 Python
python线程的几种创建方式详解
Aug 29 Python
python中对_init_的理解及实例解析
Oct 11 Python
Python中输入和输出(打印)数据实例方法
Oct 13 Python
在Python中等距取出一个数组其中n个数的实现方式
Nov 27 Python
python根据用户需求输入想爬取的内容及页数爬取图片方法详解
Aug 03 Python
如何真正的了解python装饰器
Aug 14 Python
Python configparser模块应用过程解析
Aug 14 Python
python实现xml转json文件的示例代码
Dec 30 Python
解决Django连接db遇到的问题
Aug 29 #Python
Python pandas实现excel工作表合并功能详解
Aug 29 #Python
python openCV获取人脸部分并存储功能
Aug 28 #Python
python lambda表达式在sort函数中的使用详解
Aug 28 #Python
python实现微信小程序用户登录、模板推送
Aug 28 #Python
使用Python脚本zabbix自定义key监控oracle连接状态
Aug 28 #Python
django删除表重建的实现方法
Aug 28 #Python
You might like
用PHP调用数据库的存贮过程!
2006/10/09 PHP
php文件上传的例子及参数详解
2013/12/12 PHP
ThinkPHP查询中的魔术方法简述
2014/06/25 PHP
PHP中的reflection反射机制测试例子
2014/08/05 PHP
CI框架安全类Security.php源码分析
2014/11/04 PHP
PHP简单获取多个checkbox值的方法
2016/06/13 PHP
phpstudy后门rce批量利用脚本的实现
2019/12/12 PHP
能说明你的Javascript技术很烂的五个原因分析
2011/10/28 Javascript
ajax上传时参数提交不更新等相关问题
2012/12/11 Javascript
超赞的jQuery图片滑块动画特效代码汇总
2016/01/25 Javascript
javascript对象的创建和访问
2016/03/08 Javascript
JavaScipt选取文档元素的方法(推荐)
2016/08/05 Javascript
深入理解Angular4中的依赖注入
2017/06/07 Javascript
jQuery复合事件结合toggle()方法的用法示例
2017/06/10 jQuery
Node.js+jade+mongodb+mongoose实现爬虫分离入库与生成静态文件的方法
2017/09/20 Javascript
Bootstrap 模态框自定义点击和关闭事件详解
2018/08/10 Javascript
详解JavaScript中操作符和表达式
2018/09/12 Javascript
关于element的表单组件整理笔记
2021/02/05 Javascript
Python文本处理之按行处理大文件的方法
2018/04/09 Python
python实现字符串和字典的转换
2018/09/29 Python
10分钟教你用Python实现微信自动回复功能
2018/11/28 Python
使用Python3内置文档高效学习以及官方中文文档
2019/05/19 Python
程序员的七夕用30行代码让Python化身表白神器
2019/08/07 Python
python 实现从高分辨图像上抠取图像块
2020/01/02 Python
Python通过TensorFLow进行线性模型训练原理与实现方法详解
2020/01/15 Python
利用scikitlearn画ROC曲线实例
2020/07/02 Python
CSS3中的元素过渡属性transition示例详解
2016/11/30 HTML / CSS
详解CSS3 Media Queries中媒体属性的使用
2016/02/29 HTML / CSS
意大利奢侈品网站:Italist
2016/08/23 全球购物
美国著名首饰网站:BaubleBar
2016/08/29 全球购物
Habitat家居英国官方网站:沙发、家具、照明、厨房和户外
2019/12/12 全球购物
面试后感谢信怎么写
2014/02/01 职场文书
教师现实表现材料
2014/02/14 职场文书
马丁路德金演讲稿
2014/05/19 职场文书
党员个人党性分析材料
2014/12/18 职场文书
详细聊聊MySQL中慢SQL优化的方向
2021/08/30 MySQL