相关文章推荐
英勇无比的大蒜  ·  Azure Functions C# ...·  2 年前    · 
开朗的松鼠  ·  計算函式 (DAX) - DAX | ...·  2 年前    · 
没有腹肌的海豚  ·  opencv ...·  2 年前    · 

在python中,经常用到 MySQLdb 操作MySQL数据库。
在实现上, MySQLdb 并不是纯python的,而是封装了MySQL C API库 _mysql

对于MySQLdb是否支持 read_timeout ,其 使用手册 中对这个参数只字未提。所以, read_timeout 是否真的可用,是存在疑惑的。stack overflow上面也有人问到同样的 问题

接下来,我们从 MySQLdb 的源码库 MySQLdb-python github地址 开始,看下是否支持 read_timeout

MySQLdb 的源码

先看下代码库中的 HISTORY 文件 :

beta 4
======
Added support for the MySQL read_timeout option. Contributed by
Jean Schurger (jean@schurger.org).
Added a workaround so that the MySQL character set utf8mb4 works with Python; utf8 is substituted
on the Python side.

其中,已经明确提到,已经对参数read_timeout提供了支持。

再来看下,底层代码是如何实现的_mysql.c:

/* According to https://dev.mysql.com/doc/refman/5.1/en/mysql-options.html
   The MYSQL_OPT_READ_TIMEOUT apear in the version 5.1.12 */
#if MYSQL_VERSION_ID > 50112
#define HAVE_MYSQL_OPT_TIMEOUTS 1
#endif
#ifdef HAVE_MYSQL_OPT_TIMEOUTS
	if (read_timeout) {
		unsigned int timeout = read_timeout;
		mysql_options(&(self->connection), MYSQL_OPT_READ_TIMEOUT,
				(char *)&timeout);
	if (write_timeout) {
		unsigned int timeout = write_timeout;
		mysql_options(&(self->connection), MYSQL_OPT_WRITE_TIMEOUT,
				(char *)&timeout);
#endif

从代码中,可以看到,MySQL从5.1.12版本开始支持read_timeout.

MySQLdb在具体实现上,通过
mysql_options()设置参数MYSQL_OPT_READ_TIMEOUT,来实现读超时。

关于MYSQL_OPT_READ_TIMEOUTMYSQL_OPT_WRITE_TIMEOUT,可以参考MySQL官方文档说明
mysql_options()

下面来看下MySQLdb-python中的read_timeout如何使用。

read_timeout例子

下面例子中,设置read_timeout为5s, 并使sql语句执行超过5s。
查看其执行结果。

import MySQLdb
from datetime import datetime
host = "127.0.0.1"
port = 3306
sql = "select sleep(10)"
user = "root"
passwd = "Aa123456"
conn = MySQLdb.connect(host=host, port=port, user=user,passwd=passwd, connect_timeout=2, read_timeout=5, charset="utf8")
cursor = conn.cursor()
print("now:", datetime.now())
try:
        cursor.execute(sql)
except Exception as e:
        print("now:", datetime.now())
        print("except:", e)
        raise
ret = cursor.fetchone()
print("result:", ret)
cursor.close()
conn.close()
print("end")

output:

now: 2019-07-28 15:57:40.424942
now: 2019-07-28 15:57:45.425193
except: (2013, 'Lost connection to MySQL server during query')
Traceback (most recent call last):
  File "read_timeout.py", line 19, in <module>
    cursor.execute(sql)
  File "/Users/lanyang/workspace/orange-service/.venv/lib/python3.6/site-packages/MySQLdb/cursors.py", line 198, in execute
    res = self._query(query)
  File "/Users/lanyang/workspace/orange-service/.venv/lib/python3.6/site-packages/MySQLdb/cursors.py", line 304, in _query
    db.query(q)
  File "/Users/lanyang/workspace/orange-service/.venv/lib/python3.6/site-packages/MySQLdb/connections.py", line 217, in query
    _mysql.connection.query(self, query)
MySQLdb._exceptions.OperationalError: (2013, 'Lost connection to MySQL server during query')

可以看到,当sql语句执行超过5s后,连接被断开。
已经达到预期的效果。

Python 操作 MySQL 数据库

MySQLdb-python安装

MySQLdb-python使用文档

MySQLdb-python github地址

MySQL C API

在python中,经常用到 MySQLdb操作MySQL数据库。在实现上,MySQLdb并不是纯python的,而是封装了MySQL C API库_mysql。对于MySQLdb是否支持read_timeout,其使用手册中对这个参数只字未提。所以,read_timeout是否真的可用,是存在疑惑的。stack overflow上面也有人问到同样的问题。接下来,我们从MySQLdb的源码库M...
标签: 数据库 pythonconnections 模块类:Connection 用法:执行 pymysql.connect() 得到。而不是构造函数 Connection()。 pymysql.connect() 的参数即为 Connection() 构造函数的参数。 构造函数: pymysql.connections.Connection(self, host=None,
1. 更改timeout参数 出现这个问题顺便就了解了一下mysql中的timeout都有什么: mysql> show variables like '%timeout%'; +-----------------------------+----------+ | Variab 清华:https://pypi.tuna.tsinghua.edu.cn/simple 阿里云:http://mirrors.aliyun.com/pypi/simple/ 中国科技大学 https://pypi.mirrors.ustc.edu.cn/simple/ 豆瓣:http://pypi.douban.com/simple/ 在Linux下: 修改 ~/.pip/pip.conf (没有就创建一个文件夹及文件。文件夹要加“.”,表示是隐藏文件夹) 2. 安装失败截图: eg. 以opencv-python库安装为例 cmd输入pip install opencv-python回车进行安装,大部分会出现Read timed out安装超时问题! 2. 解决:借用pip国内源 pip install opencv-python -i https://mirrors.aliyun.com/pypi/simple/ 巨快!!! (安装其他库也适用 eg. matplotlib) 3. 其他pi