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 相关文章推荐
Django Highcharts制作图表
Aug 27 Python
python正则表达式匹配[]中间为任意字符的实例
Dec 25 Python
通过python实现随机交换礼物程序详解
Jul 10 Python
Python变量作用域LEGB用法解析
Feb 04 Python
python如何将两张图片生成为全景图片
Mar 05 Python
解决django无法访问本地static文件(js,css,img)网页里js,cs都加载不了
Apr 07 Python
Python如何使用队列方式实现多线程爬虫
May 12 Python
Python Selenium实现无可视化界面过程解析
Aug 25 Python
Pycharm常用快捷键总结及配置方法
Nov 14 Python
使用python向MongoDB插入时间字段的操作
May 18 Python
Python 中 Shutil 模块详情
Nov 11 Python
pandas进行数据输入和输出的方法详解
Mar 23 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一个解析字符串排列数组的方法
2015/05/12 PHP
深入解析PHP的Laravel框架中的event事件操作
2016/03/21 PHP
深入聊聊Array的sort方法的使用技巧.详细点评protype.js中的sortBy方法
2007/04/12 Javascript
javascript 类方法定义还是有点区别
2009/04/15 Javascript
Prototype String对象 学习
2009/07/19 Javascript
JavaScript生成随机数的4种自定义函数分享
2015/02/28 Javascript
js控制网页前进和后退的方法
2015/06/08 Javascript
JavaScript iframe数据共享接口实现方法
2016/01/06 Javascript
js事件处理程序跨浏览器解决方案
2016/03/27 Javascript
JQ选择器_选择同类元素的第N个子元素的实现方法
2016/09/08 Javascript
vue-router 路由基础的详解
2017/10/17 Javascript
Vue中的scoped实现原理及穿透方法
2018/05/15 Javascript
微信小程序后台持续定位功能使用详解
2019/08/23 Javascript
js实现前端界面导航栏下拉列表
2020/08/27 Javascript
详解Python中如何写控制台进度条的整理
2018/03/07 Python
使用python获取csv文本的某行或某列数据的实例
2018/04/03 Python
python 不以科学计数法输出的方法
2018/07/16 Python
python flask实现分页的示例代码
2018/08/02 Python
Python3利用Dlib实现摄像头实时人脸检测和平铺显示示例
2019/02/21 Python
对Python中小整数对象池和大整数对象池的使用详解
2019/07/09 Python
python使用 cx_Oracle 模块进行查询操作示例
2019/11/28 Python
pycharm2020.2 配置使用的方法详解
2020/09/16 Python
使用html2canvas将页面转成图并使用用canvas2image下载
2019/04/04 HTML / CSS
HTML5 Web存储方式的localStorage和sessionStorage进行数据本地存储案例应用
2012/12/09 HTML / CSS
台湾母婴用品限时团购:妈咪爱
2018/08/03 全球购物
DBA数据库管理员JAVA程序员架构师必看
2016/02/07 面试题
新闻专业大学生找工作的自我评价
2013/10/30 职场文书
师范院校学生自荐信范文
2013/12/27 职场文书
综治维稳工作承诺书
2014/08/30 职场文书
九九重阳节标语
2014/10/07 职场文书
驳回起诉民事裁定书
2015/05/19 职场文书
芙蓉镇观后感
2015/06/10 职场文书
2016初一新生军训心得体会
2016/01/11 职场文书
什么是执行力?9个故事告诉您:成功绝非偶然!
2019/07/05 职场文书
CSS3 实现的图片悬停的切换按钮
2021/04/13 HTML / CSS