给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使用正则匹配实现抓图代码分享
Apr 02 Python
Python函数的周期性执行实现方法
Aug 13 Python
pytorch + visdom 处理简单分类问题的示例
Jun 04 Python
python skimage 连通性区域检测方法
Jun 21 Python
用Python解决x的n次方问题
Feb 08 Python
详解Python_shutil模块
Mar 15 Python
Django框架序列化与反序列化操作详解
Nov 01 Python
Python 输出详细的异常信息(traceback)方式
Apr 08 Python
Tensorflow tf.nn.depthwise_conv2d如何实现深度卷积的
Apr 20 Python
无需压缩软件,用python帮你操作压缩包
Aug 17 Python
Python colormap库的安装和使用详情
Oct 06 Python
Python pygame实现中国象棋单机版源码
Jun 20 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
pdo中使用参数化查询sql
2011/08/11 PHP
php中存储用户ID和密码到mysql数据库的方法
2013/02/06 PHP
PHP实现JS中escape与unescape的方法
2016/07/11 PHP
PHP7匿名类用法分析
2016/09/26 PHP
php mysql_list_dbs()函数用法示例
2017/03/29 PHP
yii2 url重写并隐藏index.php方法
2018/12/10 PHP
laravel7学习之无限级分类的最新实现方法
2020/09/30 PHP
js window.onload 加载多个函数的方法
2009/11/02 Javascript
jQuery Ajax 实例全解析
2011/04/20 Javascript
各浏览器对click方法的支持差异小结
2011/07/31 Javascript
js中replace的用法总结
2013/12/27 Javascript
jquery动态切换背景图片的简单实现方法
2016/05/14 Javascript
浅谈Nodejs应用主文件index.js
2016/08/28 NodeJs
jQuery ajax 当async为false时解决同步操作失败的问题
2016/11/18 Javascript
bootstrap侧边栏圆点导航
2017/01/11 Javascript
JS实现复制内容到剪贴板功能
2017/02/05 Javascript
微信小程序实现图片上传放大预览删除代码
2020/06/28 Javascript
在vue项目中使用md5加密的方法
2018/09/14 Javascript
浅谈VUE防抖与节流的最佳解决方案(函数式组件)
2019/05/22 Javascript
浅探express路由和中间件的实现
2019/09/30 Javascript
在Vue 中获取下拉框的文本及选项值操作
2020/08/13 Javascript
微信小程序实现选项卡滑动切换
2020/10/22 Javascript
[02:40]2018年度DOTA2最佳新人-完美盛典
2018/12/16 DOTA
Android 兼容性问题:java.lang.UnsupportedOperationException解决办法
2017/03/19 Python
Python类的继承和多态代码详解
2017/12/27 Python
Pycharm导入Python包,模块的图文教程
2018/06/13 Python
Python + Requests + Unittest接口自动化测试实例分析
2019/12/12 Python
详解HTML5通讯录获取指定多个人的信息
2016/12/20 HTML / CSS
史蒂夫·马登加拿大官网:Steve Madden加拿大
2017/11/18 全球购物
美国知名的旅游网站:OneTravel
2018/10/09 全球购物
会计找工作求职信范文
2013/12/09 职场文书
绩效工资实施方案
2014/03/15 职场文书
英语感谢信范文
2015/01/20 职场文书
2015年学校精神文明工作总结
2015/05/27 职场文书
iPhone13 Pro外观确定,升级4800万镜头,4月20日发新品
2021/04/15 数码科技
python 模拟在天空中放风筝的示例代码
2021/04/21 Python