python mysql 断连报错处理
在使用python 对wordpress tag 进行细化代码处理时,遇到了调用MySQLdb模块时的出错,由于错误提示和问题原因相差甚远,查看了N久代码也未发现代码有问题。后来问了下师傅,被告知MySQLdb里有一个断接的坑 ,需要进行数据库重连解决。
一、报错代码及提示
运行出错的代码如下:
1import MySQLdb
2def getTerm(db,tag):
3 cursor = db.cursor()
4 query = "SELECT term_id FROM wp_terms where name=%s "
5 count = cursor.execute(query,tag)
6 rows = cursor.fetchall()
7 db.commit()
8 #db.close()
9 if count:
10 term_id = [int(rows[id][0]) for id in range(count)]
11 return term_id
12 else:return None
13def addTerm(db,tag):
14 cursor = db.cursor()
15 query = "INSERT into wp_terms (name,slug,term_group) values (%s,%s,0)"
16 data = (tag,tag)
17 cursor.execute(query,data)
18 db.commit()
19 term_id = cursor.lastrowid
20 sql = "INSERT into wp_term_taxonomy (term_id,taxonomy,description) values (%s,'post_tag',%s) "
21 value = (term_id,tag)
22 cursor.execute(sql,value)
23 db.commit()
24 db.close()
25 return int(term_id)
26dbconn = MySQLdb.connect(host='localhost', user='root', passwd='123456', db='361way', port=3306, charset='utf8', init_command='set names utf8')
27tags = ['mysql','1111','aaaa','bbbb','ccccc','php','abc','python','java']
28tagids = []
29for tag in tags:
30 termid = getTerm(dbconn,tag)
31 if termid:
32 print tag, 'tag id is ',termid
33 tagids.extend(termid)
34 else:
35 termid = addTerm(dbconn,tag)
36 print 'add tag',tag,'id is ' ,termid
37 tagids.append(termid)
38print 'tag id is ',tagids
直接可以执行,在第for循环里第二次调用getTerm函数时,报错如下:
1Traceback (most recent call last):
2 File "a.py", line 40, in <module>
3 termid = getTerm(dbconn,tag)
4 File "a.py", line 11, in getTerm
5 count = cursor.execute(query,tag)
6 File "/usr/lib64/python2.6/site-packages/MySQLdb/cursors.py", line 154, in execute
7 charset = db.character_set_name()
8_mysql_exceptions.InterfaceError: (0, '')
二、解决方法
初始时以为是编码问题了,又细核对了几遍未发现编码有问题,在python代码里也未发现异常。后来问过师傅后,师傅来了句提示:
只看代码有啥用,mysql 的超时时间调长点或捕获异常从连,原因是cursor. connection 没有关闭,但是socket已经断了cursor 这个行为不会再建立一次socket的重新执行一次MysqlDB.connect()
看的有点懵懂,先从mysql 里查看了所有timeout相关的变量
1mysql> show GLOBAL VARIABLES like "%timeout%";
2+----------------------------+-------+
3| Variable_name | Value |
4+----------------------------+-------+
5| connect_timeout | 10 |
6| delayed_insert_timeout | 300 |
7| innodb_lock_wait_timeout | 50 |
8| innodb_rollback_on_timeout | OFF |
9| interactive_timeout | 28800 |
10| net_read_timeout | 30 |
11| net_write_timeout | 60 |
12| slave_net_timeout | 3600 |
13| table_lock_wait_timeout | 50 |
14| wait_timeout | 28800 |
15+----------------------------+-------+
1610 rows in set (0.00 sec)
发现最小的超时时间是10s ,而我的程序执行起来显然就不了10s 。因为之前查过相关的报错,这里估计这个很可能是另外一个报错:2006,MySQL server has gone away 。即然和这个超时时间应该没关系,那就尝试通过MySQLdb ping测试,如果捕获异常,就再进行重连,修改后的代码为:
1#!/usr/bin/python
2#coding=utf-8
3import MySQLdb
4def getTerm(db,tag):
5 cursor = db.cursor()
6 query = "SELECT term_id FROM wp_terms where name=%s "
7 count = cursor.execute(query,tag)
8 rows = cursor.fetchall()
9 db.commit()
10 #db.close()
11 if count:
12 term_id = [int(rows[id][0]) for id in range(count)]
13 print term_id
14 return term_id
15 else:return None
16def addTerm(db,tag):
17 cursor = db.cursor()
18 query = "INSERT into wp_terms (name,slug,term_group) values (%s,%s,0)"
19 data = (tag,tag)
20 cursor.execute(query,data)
21 db.commit()
22 term_id = cursor.lastrowid
23 sql = "INSERT into wp_term_taxonomy (term_id,taxonomy,description) values (%s,'post_tag',%s) "
24 value = (term_id,tag)
25 cursor.execute(sql,value)
26 db.commit()
27 db.close()
28 return int(term_id)
29dbconn = MySQLdb.connect(host='localhost', user='root', passwd='123456', db='361way', port=3306, charset='utf8', init_command='set names utf8')
30tags = ['mysql','1111','aaaa','bbbb','ccccc','php','abc','python','java']
31if __name__ == "__main__":
32 tagids = []
33 for tag in tags:
34 try:
35 dbconn.ping()
36 except:
37 print 'mysql connect have been close'
38 dbconn = MySQLdb.connect(host='localhost', user='root', passwd='123456', db='361way', port=3306, charset='utf8', init_command='set names utf8')
39 termid = getTerm(dbconn,tag)
40 if termid:
41 print tag, 'tag id is ',termid
42 tagids.extend(termid)
43 else:
44 termid = addTerm(dbconn,tag)
45 print 'add tag',tag,'id is ' ,termid
46 tagids.append(termid)
47 print 'All tags id is ',tagids
再执行发现竟然OK了,而细看下结果,发现基本上每1-2次getTerm或addTerm函数调用就会打印一次mysql connect have been clos
e 。这里问题虽然已经解决,不过并未细挖到真正的根因。
三、建议
从网上要看的结果来看MySQLdb还有不支持长连接的坑,这个可以通过上面提到的修改my.cnf参数解决,也可以考虑使用其他支持设置timeout时间mysql模块。另外,也建议使用MySQLdb时,可以考虑使用一个对其二次封装的模块torndb —- A lightweight wrapper around MySQLdb 。
具体使用可以参看:http://tornado.readthedocs.org/en/branch2.4/database.html
捐赠本站(Donate)
如您感觉文章有用,可扫码捐赠本站!(If the article useful, you can scan the QR code to donate))
- Author: shisekong
- Link: https://blog.361way.com/python-mysqldb-disconnection/4061.html
- License: This work is under a 知识共享署名-非商业性使用-禁止演绎 4.0 国际许可协议. Kindly fulfill the requirements of the aforementioned License when adapting or creating a derivative of this work.