国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > Python > 正文

Python中MySQLdb和torndb模塊對MySQL的斷連問題處理

2019-11-25 17:02:50
字體:
來源:轉載
供稿:網友

在使用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相關的變量

mysql> show GLOBAL VARIABLES like "%timeout%";
+----------------------------+-------+| Variable_name       | Value |+----------------------------+-------+| connect_timeout      | 10  || delayed_insert_timeout   | 300  || innodb_lock_wait_timeout  | 50  || innodb_rollback_on_timeout | OFF  || interactive_timeout    | 28800 || net_read_timeout      | 30  || net_write_timeout     | 60  || slave_net_timeout     | 3600 || table_lock_wait_timeout  | 50  || wait_timeout        | 28800 |+----------------------------+-------+10 rows in set (0.00 sec)

發現最小的超時時間是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模塊的代碼

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)def addCTag(db,data):    cursor = db.cursor()    query = '''INSERT INTO `wp_term_relationships` (      `object_id` ,      `term_taxonomy_id`      )      VALUES (      %s, %s) '''    cursor.executemany(query,data)    db.commit()    db.close()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:    if termid:        try:         dbconn.ping()        except:         dbconn = MySQLdb.connect(host='localhost', user='root', passwd='123456', db='361way', port=3306, charset='utf8', init_command='set names utf8')         print tag, 'tag id is ',termid        termid = getTerm(dbconn,tag)        tagids.extend(termid)    else:        try:         dbconn.ping()        except:         dbconn = MySQLdb.connect(host='localhost', user='root', passwd='123456', db='361way', port=3306, charset='utf8', init_command='set names utf8')        termid = addTerm(dbconn,tag)        print 'add tag',tag,'id is ' ,termid        tagids.append(termid)print 'tag id is ',tagidspostid = '35'tagids = list(set(tagids))ctagdata = []for tagid in tagids:  ctagdata.append((postid,tagid))try:  dbconn.ping()except:  dbconn = MySQLdb.connect(host='localhost', user='root', passwd='123456', db='361way', port=3306, charset='utf8', init_command='set names utf8')  addCTag(dbconn,ctagdata)

使用torndb的代碼

#!/usr/bin/python#coding=utf-8import torndbdef getTerm(db,tag):    query = "SELECT term_id FROM wp_terms where name=%s "    rows = db.query(query,tag)    termid = []    for row in rows:      termid.extend(row.values())    return termiddef addTerm(db,tag):    query = "INSERT into wp_terms (name,slug,term_group) values (%s,%s,0)"    term_id = db.execute_lastrowid(query,tag,tag)    sql = "INSERT into wp_term_taxonomy (term_id,taxonomy,description) values (%s,'post_tag',%s) "    db.execute(sql,term_id,tag)    return term_iddef addCTag(db,data):    query = "INSERT INTO wp_term_relationships (object_id,term_taxonomy_id) VALUES (%s, %s) "    db.executemany(query,data)dbconn = torndb.Connection('localhost:3306','361way',user='root',password='123456')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 'All tags id is ',tagidspostid = '35'tagids = list(set(tagids))ctagdata = []for tagid in tagids:  ctagdata.append((postid,tagid))addCTag(dbconn,ctagdata)

從兩者的代碼上來看,使用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                    關閉后再連接
使用示例:

mysql> CREATE TABLE `ceshi` (`id` int(1) NULL AUTO_INCREMENT ,`num` int(1) NULL ,PRIMARY KEY (`id`));
>>> import torndb>>> db = torndb.Connection("127.0.0.1","數據庫名","用戶名", "密碼", 24*3600)  # 24*3600為超時時間>>> get_id1 = db.execute_lastrowid("insert ceshi(num) values('1')")>>> print get_id11>>> args1 = [('2'),('3'),('4')]>>> get1 = db.executemany("insert ceshi(num) values(%s)", args1)>>> print get12>>> rows = db.iter("select * from ceshi")>>> for i in rows:… print i
3.報錯

在使用過程中可能遇到的錯誤:

 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)

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 陕西省| 新平| 汽车| 平和县| 克什克腾旗| 法库县| 新昌县| 龙井市| 赣榆县| 贡山| 潢川县| 正定县| 禄丰县| 丰顺县| 沙田区| 保康县| 正安县| 南华县| 墨玉县| 工布江达县| 通河县| 天等县| 毕节市| 永城市| 天台县| 涞水县| 华阴市| 文登市| 达拉特旗| 二连浩特市| 卢氏县| 胶南市| 上思县| 科技| 吐鲁番市| 岱山县| 乌鲁木齐市| 麦盖提县| 治县。| 梅河口市| 江华|