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中的yield使用方法
Feb 11 Python
python检查指定文件是否存在的方法
Jul 06 Python
tensorflow训练中出现nan问题的解决
Feb 10 Python
PyQt5每天必学之拖放事件
Aug 27 Python
Django教程笔记之中间件middleware详解
Aug 01 Python
opencv python 图像轮廓/检测轮廓/绘制轮廓的方法
Jul 03 Python
用python实现英文字母和相应序数转换的方法
Sep 18 Python
python 利用pyttsx3文字转语音过程详解
Sep 25 Python
python pygame实现挡板弹球游戏
Nov 25 Python
Python GUI编程学习笔记之tkinter界面布局显示详解
Mar 30 Python
python里glob模块知识点总结
Jan 05 Python
详解python字符串驻留技术
May 21 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导入导出CSV文件
2014/11/03 PHP
PHP实现通过URL提取根域名
2016/03/31 PHP
PHP函数shuffle()取数组若干个随机元素的方法分析
2016/04/02 PHP
PHP数组去重的更快实现方式分析
2018/05/09 PHP
laravel手动创建数组分页的实现代码
2018/06/07 PHP
PHP检测一个数组有没有定义的方法步骤
2019/07/20 PHP
学习ExtJS accordion布局
2009/10/08 Javascript
jQuery学习笔记[1] jQuery中的DOM操作
2010/12/03 Javascript
基于jQuery的计算文本框字数的代码
2012/06/06 Javascript
使用命令对象代替switch语句的写法示例
2015/02/28 Javascript
Javascript基础回顾之(一) 类型
2017/01/31 Javascript
神级程序员JavaScript300行代码搞定汉字转拼音
2017/05/20 Javascript
荐书|您有一份JavaScript书单待签收
2017/07/21 Javascript
ES6学习笔记之map、set与数组、对象的对比
2018/03/01 Javascript
JS实现将链接生成二维码并转为图片的方法
2018/03/17 Javascript
详解vue-cli项目开发/生产环境代理实现跨域请求
2019/07/23 Javascript
Python数据分析之真实IP请求Pandas详解
2016/11/18 Python
用python处理MS Word的实例讲解
2018/05/08 Python
对pandas通过索引提取dataframe的行方法详解
2019/02/01 Python
python算法题 链表反转详解
2019/07/02 Python
解决python gdal投影坐标系转换的问题
2020/01/17 Python
Python GUI编程学习笔记之tkinter控件的介绍及基本使用方法详解
2020/03/30 Python
python调用私有属性的方法总结
2020/07/24 Python
详解html5 canvas 微信海报分享(个人爬坑)
2018/01/12 HTML / CSS
canvas实现滑动验证的实现示例
2020/08/11 HTML / CSS
欧舒丹美国官网:L’Occitane美国
2018/02/23 全球购物
The Hut英国:英国领先的豪华在线百货商店
2019/07/26 全球购物
迪士尼法国在线商店:shopDisney FR
2020/12/03 全球购物
公务员个人自我评价分享
2013/11/06 职场文书
《小小竹排画中游》教学反思
2014/02/26 职场文书
企业安全生产规章制度
2015/08/06 职场文书
爱岗敬业先进典型事迹材料(2016推荐版)
2016/02/26 职场文书
详解Python 3.10 中的新功能和变化
2021/04/28 Python
canvas绘制折线路径动画实现
2021/05/12 Javascript
python process模块的使用简介
2021/05/14 Python
2021年国漫热度排行前十,完美世界上榜,第四是美国动画作品
2022/03/18 国漫