给Python中的MySQLdb模块添加超时功能的教程


Posted in Python onMay 05, 2015

使用Python操作MySQL数据库的时候常使用MySQLdb这个模块。

今天在开发的过程发现MySQLdb.connect有些参数没法设置。通过这个页面我们可以看到在connect的时候,可以设置的option和client_flags和MySQL c api相比差不少。

一个很重要的参数 MYSQL_OPT_READ_TIMEOUT没法设置,这个参数如果不设置,极致状况MySQL处于hang住,自动切换IP漂移,客户端无法重连到新MySQL。

给MySQLdb加Option很简单,只要修改_mysql.c这个把Python对象映射到MySQL操作的文件,添加参数,再加一段mysql_option即可。

下面是修改后的git diff 文件

?View Code BASH

diff --git a/_mysql.c b/_mysql.c
index d42cc54..61a9b34 100644
--- a/_mysql.c
+++ b/_mysql.c
@@ -489,9 +489,10 @@ _mysql_ConnectionObject_Initialize(
"named_pipe", "init_command",
"read_default_file", "read_default_group",
"client_flag", "ssl",
-                 "local_infile",
+                 "local_infile", "read_timeout",
NULL } ;
int connect_timeout = 0;
+    int read_timeout = 0;
int compress = -1, named_pipe = -1, local_infile = -1;
char *init_command=NULL,
*read_default_file=NULL,
@@ -500,7 +501,7 @@ _mysql_ConnectionObject_Initialize(
self->converter = NULL;
self->open = 0;
check_server_init(-1);
-    if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|ssssisOiiisssiOi:connect",
+    if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|ssssisOiiisssiOii:connect",
kwlist,
&host, &user, &passwd, &db,
&port, &unix_socket, &conv,
@@ -509,7 +510,8 @@ _mysql_ConnectionObject_Initialize(
&init_command, &read_default_file,
&read_default_group,
&client_flag, &ssl,
-                    &local_infile /* DO NOT PATCH FOR RECONNECT, IDIOTS
+                    &local_infile, &read_timeout
+                    /* DO NOT PATCH FOR RECONNECT, IDIOTS
IF YOU DO THIS, I WILL NOT SUPPORT YOUR PACKAGES. */
))
return -1;
@@ -540,6 +542,12 @@ _mysql_ConnectionObject_Initialize(
mysql_options(&(self->connection), MYSQL_OPT_CONNECT_TIMEOUT,
(char *)&timeout);
}
+
+    if (read_timeout) {
+        unsigned int timeout = read_timeout;
+        mysql_options(&(self->connection), MYSQL_OPT_READ_TIMEOUT, (char *)&timeout);
+    }
+
if (compress != -1) {
mysql_options(&(self->connection), MYSQL_OPT_COMPRESS, 0);
client_flag |= CLIENT_COMPRESS;

代码修改完毕,python setup.py install 即可,如果出现mysql_config找不到的问题。你还要修改setup_posix.py文件。

hoterran@hoterran-laptop:~/Projects/MySQL-python-1.2.3$ git diff setup_posix.py
diff --git a/setup_posix.py b/setup_posix.py
index 86432f5..f4f08f1 100644
--- a/setup_posix.py
+++ b/setup_posix.py
@@ -23,7 +23,7 @@ def mysql_config(what):
     if ret/256 > 1:
       raise EnvironmentError("%s not found" % (mysql_config.path,))
   return data
-mysql_config.path = "mysql_config"
+mysql_config.path = "/usr/local/mysql/bin/mysql_config"

 def get_config():
   import os, sys

编译通过,我们来试试添加的read_timeout这个参数。

conn = MySQLdb.connect(host = DB_SERVER,user = DB_USERNAME,passwd = DB_PASSWORD,db = DB_NAME, port=int(DB_PORT), client_flag = 2, read_timeout = 10)

然后执行语句前,你试着把mysql用gdb hang住10s后,python就会异常抛错

OperationalError: (2013, 'Lost connection to MySQL server during query')
 >/home/hoterran/Projects/dbaas/trunk/dbtest.py(18)()
 >mydb.execute_sql(conn, sql)
(Pdb)
--Return--
> /home/hoterran/Projects/dbaas/trunk/dbtest.py(18)()->None
> mydb.execute_sql(conn, sql)
(Pdb)
OperationalError: (2013, 'Lost connection to MySQL server during query')
> <string>(1)<module>()->None

Python 相关文章推荐
利用python获取某年中每个月的第一天和最后一天
Dec 15 Python
Python正则替换字符串函数re.sub用法示例
Jan 19 Python
Python决策树之基于信息增益的特征选择示例
Jun 25 Python
Flask框架URL管理操作示例【基于@app.route】
Jul 23 Python
python 重命名轴索引的方法
Nov 10 Python
利用python list完成最简单的DB连接池方法
Aug 09 Python
Python谱减法语音降噪实例
Dec 18 Python
Python基于read(size)方法读取超大文件
Mar 12 Python
python实现俄罗斯方块小游戏
Apr 24 Python
Python实现手绘图效果实例分享
Jul 22 Python
python3 通过 pybind11 使用Eigen加速代码的步骤详解
Dec 07 Python
基于PyTorch实现一个简单的CNN图像分类器
May 29 Python
用Python实现一个简单的多线程TCP服务器的教程
May 05 #Python
简单介绍Python中的try和finally和with方法
May 05 #Python
python中的闭包用法实例详解
May 05 #Python
Python闭包实现计数器的方法
May 05 #Python
深入探究Python中变量的拷贝和作用域问题
May 05 #Python
Python使用metaclass实现Singleton模式的方法
May 05 #Python
python中查看变量内存地址的方法
May 05 #Python
You might like
php导出csv格式数据并将数字转换成文本的思路以及代码分享
2014/06/05 PHP
ExtJS GTGrid 简单用户管理
2009/07/01 Javascript
Javascript解决常见浏览器兼容问题的12种方法
2010/01/04 Javascript
Jquery 滑入滑出效果实现代码
2010/03/27 Javascript
JavaScript初学者需要了解10个小技巧
2010/08/25 Javascript
Extjs EditorGridPanel中ComboBox列的显示问题
2011/07/04 Javascript
那些年,我还在学习jquery 学习笔记
2012/03/05 Javascript
JavaScript学习笔记之基础语法
2015/01/22 Javascript
JS实现可缩放、拖动、关闭和最小化的浮动窗口完整实例
2015/03/04 Javascript
JavaScript实现LI列表数据绑定的方法
2015/08/04 Javascript
实例详解JavaScript获取链接参数的方法
2016/01/01 Javascript
利用Vue.js实现checkbox的全选反选效果
2017/01/18 Javascript
简单实现AngularJS轮播图效果
2020/04/10 Javascript
JS常用正则表达式总结【经典】
2017/05/12 Javascript
Vue中的情侣属性$dispatch和$broadcast详解
2019/03/07 Javascript
微信小程序利用云函数获取手机号码
2019/12/17 Javascript
Vue Cli3 打包配置并自动忽略console.log语句的方法
2020/04/23 Javascript
react antd表格中渲染一张或多张图片的实例
2020/10/28 Javascript
python微信跳一跳系列之自动计算跳一跳距离
2018/02/26 Python
pytorch构建网络模型的4种方法
2018/04/13 Python
Python3中详解fabfile的编写
2018/06/24 Python
Python操作rabbitMQ的示例代码
2019/03/19 Python
Python 类的魔法属性用法实例分析
2019/11/21 Python
Python实现自动打开电脑应用的示例代码
2020/04/17 Python
HTML5 Canvas 起步(2) - 路径
2009/05/12 HTML / CSS
美国新蛋IT数码商城:Newegg.com
2016/07/21 全球购物
医学专业毕业生推荐信
2013/11/14 职场文书
中学运动会广播稿
2014/01/19 职场文书
员工生日活动方案
2014/08/24 职场文书
2015年建筑工作总结报告
2015/05/04 职场文书
运动会闭幕式通讯稿
2015/07/18 职场文书
关于远足的感想
2015/08/10 职场文书
2016庆祝教师节新闻稿
2015/11/25 职场文书
2016年全国爱牙日宣传活动总结
2016/04/05 职场文书
python基于tkinter制作无损音乐下载工具
2021/03/29 Python
SpringBoot整合Redis入门之缓存数据的方法
2021/11/17 Redis