python MySQLdb 如何設置讀超時read_timeout


在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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM