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二分法实现实例
Nov 21 Python
python实现在字符串中查找子字符串的方法
Jul 11 Python
Python 列表排序方法reverse、sort、sorted详解
Jan 22 Python
Python数据分析之双色球统计单个红和蓝球哪个比例高的方法
Feb 03 Python
python使用代理ip访问网站的实例
May 07 Python
Pycharm 设置自定义背景颜色的图文教程
May 23 Python
Python直接赋值、浅拷贝与深度拷贝实例分析
Jun 18 Python
基于python的socket实现单机五子棋到双人对战
Mar 24 Python
搭建python django虚拟环境完整步骤详解
Jul 08 Python
TFRecord文件查看包含的所有Features代码
Feb 17 Python
python 读取yaml文件的两种方法(在unittest中使用)
Dec 01 Python
python 利用 PIL 将数组值转成图片的实现
Apr 12 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
全国FM电台频率大全 - 12 安徽省
2020/03/11 无线电
Cappuccino 卡布其诺咖啡之制作
2021/03/03 冲泡冲煮
PHP 5.0对象模型深度探索之类的静态成员
2008/03/27 PHP
ThinkPHP采用模块和操作分析
2011/04/18 PHP
php网站判断用户是否是手机访问的方法
2013/11/01 PHP
PHP之autoload运行机制实例分析
2014/08/28 PHP
Joomla调用系统自带编辑器的实现方法
2016/05/05 PHP
浅谈Laravel核心解读之Console内核
2018/12/02 PHP
关于eval 与new Function 到底该选哪个?
2013/04/17 Javascript
javascript 上下banner替换具体实现
2013/11/14 Javascript
改变状态栏文字的js代码
2014/06/13 Javascript
使用ajaxfileupload.js实现ajax上传文件php版
2014/06/26 Javascript
jquery插件hiAlert实现网页对话框美化
2015/05/03 Javascript
简介JavaScript中toTimeString()方法的使用
2015/06/12 Javascript
[原创]JavaScript语法高亮插件highlight.js用法详解【附highlight.js本站下载】
2016/11/01 Javascript
任意Json转成无序列表的方法示例
2016/12/09 Javascript
微信JS-SDK选取手机照片上传功能
2017/04/21 Javascript
基于Vue实现页面切换左右滑动效果
2020/06/29 Javascript
layui加载表格,绑定新增,编辑删除,查看按钮事件的例子
2019/09/06 Javascript
vue实现文字加密功能
2019/09/27 Javascript
[49:28]VP vs Optic 2018国际邀请赛小组赛BO2 第二场 8.16
2018/08/17 DOTA
Python自动重试HTTP连接装饰器
2015/04/28 Python
让Python代码更快运行的5种方法
2015/06/21 Python
Python下Fabric的简单部署方法
2015/07/14 Python
Python2和Python3中print的用法示例总结
2017/10/25 Python
python 返回列表中某个值的索引方法
2018/11/07 Python
python中wx模块的具体使用方法
2020/05/15 Python
Keras使用ImageNet上预训练的模型方式
2020/05/23 Python
css3动画效果抖动解决方法
2018/09/03 HTML / CSS
小学家长会邀请函
2014/01/23 职场文书
机械工程师岗位职责
2014/06/16 职场文书
公司人事专员岗位职责
2014/08/11 职场文书
2014年财政工作总结
2014/12/10 职场文书
六一儿童节开幕词
2015/01/29 职场文书
《多彩的民间艺术》教学反思
2016/02/16 职场文书
Python中time与datetime模块使用方法详解
2022/03/31 Python