时间:2021-05-22
在使用python 对wordpress tag 进行细化代码处理时,遇到了调用MySQLdb模块时的出错,由于错误提示和问题原因相差甚远,查看了N久代码也未发现代码有问题。后来问了下师傅,被告知MySQLdb里有一个断接的坑 ,需要进行数据库重连解决。
一、报错代码及提示
运行出错的代码如下:
import MySQLdbdef getTerm(db,tag): cursor = db.cursor() query = "SELECT term_id FROM wp_terms where name=%s " count = cursor.execute(query,tag) rows = cursor.fetchall() db.commit() #db.close() if count: term_id = [int(rows[id][0]) for id in range(count)] return term_id else:return Nonedef addTerm(db,tag): cursor = db.cursor() query = "INSERT into wp_terms (name,slug,term_group) values (%s,%s,0)" data = (tag,tag) cursor.execute(query,data) db.commit() term_id = cursor.lastrowid sql = "INSERT into wp_term_taxonomy (term_id,taxonomy,description) values (%s,'post_tag',%s) " value = (term_id,tag) cursor.execute(sql,value) db.commit() db.close() return int(term_id)dbconn = MySQLdb.connect(host='localhost', user='root', passwd='123456', db='361way', port=3306, charset='utf8', init_command='set names utf8')tags = ['mysql','1111','aaaa','bbbb','ccccc','php','abc','python','java']tagids = []for tag in tags: termid = getTerm(dbconn,tag) if termid: print tag, 'tag id is ',termid tagids.extend(termid) else: termid = addTerm(dbconn,tag) print 'add tag',tag,'id is ' ,termid tagids.append(termid)print 'tag id is ',tagids直接可以执行,在第for循环里第二次调用getTerm函数时,报错如下:
Traceback (most recent call last): File "a.py", line 40, in <module> termid = getTerm(dbconn,tag) File "a.py", line 11, in getTerm count = cursor.execute(query,tag) File "/usr/lib64/python2.6/site-packages/MySQLdb/cursors.py", line 154, in execute charset = db.character_set_name()_mysql_exceptions.InterfaceError: (0, '')二、解决方法
初始时以为是编码问题了,又细核对了几遍未发现编码有问题,在python代码里也未发现异常。后来问过师傅后,师傅来了句提示:
只看代码有啥用,mysql 的超时时间调长点或捕获异常从连,原因是
cursor. connection 没有关闭
但是socket已经断了
cursor 这个行为不会再建立一次socket的
重新执行一次MysqlDB.connect()
看的有点懵懂,先从mysql 里查看了所有timeout相关的变量
发现最小的超时时间是10s ,而我的程序执行起来显然就不了10s 。因为之前查过相关的报错,这里估计这个很可能是另外一个报错:2006,MySQL server has gone away 。即然和这个超时时间应该没关系,那就尝试通过MySQLdb ping测试,如果捕获异常,就再进行重连,修改后的代码为:
#!/usr/bin/python#coding=utf-8import MySQLdbdef getTerm(db,tag): cursor = db.cursor() query = "SELECT term_id FROM wp_terms where name=%s " count = cursor.execute(query,tag) rows = cursor.fetchall() db.commit() #db.close() if count: term_id = [int(rows[id][0]) for id in range(count)] print term_id return term_id else:return Nonedef addTerm(db,tag): cursor = db.cursor() query = "INSERT into wp_terms (name,slug,term_group) values (%s,%s,0)" data = (tag,tag) cursor.execute(query,data) db.commit() term_id = cursor.lastrowid sql = "INSERT into wp_term_taxonomy (term_id,taxonomy,description) values (%s,'post_tag',%s) " value = (term_id,tag) cursor.execute(sql,value) db.commit() db.close() return int(term_id)dbconn = MySQLdb.connect(host='localhost', user='root', passwd='123456', db='361way', port=3306, charset='utf8', init_command='set names utf8')tags = ['mysql','1111','aaaa','bbbb','ccccc','php','abc','python','java']if __name__ == "__main__": tagids = [] for tag in tags: try: dbconn.ping() except: print 'mysql connect have been close' dbconn = MySQLdb.connect(host='localhost', user='root', passwd='123456', db='361way', port=3306, charset='utf8', init_command='set names utf8') termid = getTerm(dbconn,tag) if termid: print tag, 'tag id is ',termid tagids.extend(termid) else: termid = addTerm(dbconn,tag) print 'add tag',tag,'id is ' ,termid tagids.append(termid) print 'All tags id is ',tagids再执行发现竟然OK了,而细看下结果,发现基本上每1-2次getTerm或addTerm函数调用就会打印一次'mysql connect have been close' 。
三、使用torndb模块解决mysql断连问题
1.MySQLdb和torndb的代码样例对比
torndb是facebook开源的一个基于MySQLdb二次封装的一个mysql模块,新封装的这个模块比较小,是一个只有2百多行代码的py文件。虽然代码短,功能确相较MySQLdb简便不少,并且该模块由于增加了reconnect方法和max_idel_time参数,解决了mysql的断连问题。比较下使用原生MySQLdb模块和使用torndb模块的代码:
使用MySQLdb模块的代码
使用torndb的代码
从两者的代码上来看,使用torndb模块和原生相比,发现可以省略如下两部分:
torndb模块不需要db.cursor进行处理,无不需要db.comment提交,torndb是自动提交的;
torndb不需要在每次调用时,进行db.ping()判断数据库socket连接是否断开,因为torndb增加了reconnect方法,支持自动重连。
2.torndb的方法
torndb提供的参数和方法有:
execute 执行语句不需要返回值的操作。
execute_lastrowid 执行后获得表id,一般用于插入后获取返回值。
executemany 可以执行批量插入。返回值为第一次请求的表id。
executemany_rowcount 批量执行。返回值为第一次请求的表id。
get 执行后获取一行数据,返回dict。
iter 执行查询后,返回迭代的字段和数据。
query 执行后获取多行数据,返回是List。
close 关闭
max_idle_time 最大连接时间
reconnect 关闭后再连接
使用示例:
在使用过程中可能遇到的错误:
File "/home/361way/database.py", line 145, in execute_lastrowid self._execute(cursor, query, parameters) File "/home/361way/database.py", line 207, in _execute return cursor.execute(query, parameters) File "/usr/lib/pymodules/python2.7/MySQLdb/cursors.py", line 159, in execute query = query % db.literal(args)TypeError: not enough arguments for format string写上面的代码时,我刚开始还是试着使用MySQLdb模块的方式引用数据,结果发现报参数的错误 ,经查看代码发现 ,torndb在使用几个sql方法时较MySQLdb精简过了。具体各个方法的传参方法如下(注意参数个数):
close()reconnect()iter(query, *parameters, **kwparameters)query(query, *parameters, **kwparameters)get(query, *parameters, **kwparameters)execute(query, *parameters, **kwparameters)execute_lastrowid(query, *parameters, **kwparameters)execute_rowcount(query, *parameters, **kwparameters)executemany(query, parameters)executemany_lastrowid(query, parameters)executemany_rowcount(query, parameters)update(query, *parameters, **kwparameters)updatemany(query, parameters)insert(query, *parameters, **kwparameters)insertmany(query, parameters)声明:本页内容来源网络,仅供用户参考;我单位不保证亦不表示资料全面及准确无误,也不保证亦不表示这些资料为最新信息,如因任何原因,本网内容或者用户因倚赖本网内容造成任何损失或损害,我单位将不会负任何法律责任。如涉及版权问题,请提交至online#300.cn邮箱联系删除。
pymsql是Python中操作MySQL的模块,其使用方法和MySQLdb几乎相同。但目前pymysql支持python3.x而后者不支持3.x版本。适用环境
之前用的Python2,连接MySQL用的是MySQLdb。现在换成python3.x了,由于MySQLdb模块还不支持Python3.x,所以Python3.
pymsql是Python中操作MySQL的模块,其使用方法和MySQLdb几乎相同。但目前pymysql支持python3.x而后者不支持3.x版本。本文环境
由于MySQLdb模块还不支持Python3.x,所以Python3.x如果想连接MySQL需要安装pymysql模块。pymysql模块可以通过pip安装。但
使用Python操作MySQL数据库的时候常使用MySQLdb这个模块。今天在开发的过程发现MySQLdb.connect有些参数没法设置。通过这个页面我们可以