在python中,常常用到 MySQLdb
操做MySQL数据库。 在实现上,MySQLdb
并非纯python的,而是封装了MySQL C API库_mysql
。html
对于MySQLdb是否支持read_timeout
,其使用手册中对这个参数只字未提。因此,read_timeout
是否真的可用,是存在疑惑的。stack overflow上面也有人问到一样的问题。python
接下来,咱们从MySQLdb
的源码库MySQLdb-python github地址开始,看下是否支持read_timeout
。mysql
MySQLdb
的源码
先看下代码库中的HISTORY
文件:git
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
提供了支持。github
再来看下,底层代码是如何实现的_mysql.c:sql
/* 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
,来实现读超时。api
关于MYSQL_OPT_READ_TIMEOUT
和MYSQL_OPT_WRITE_TIMEOUT
,能够参考MySQL官方文档说明 mysql_options()。ide
下面来看下MySQLdb-python
中的read_timeout
如何使用。fetch
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后,链接被断开。 已经达到预期的效果。