-
1.錯誤代碼
import MySQLdb if __name__ == '__main__': dbItem={} dbItem['host']='127.0.0.1' dbItem['port']=3306 dbItem['user']='root' dbItem['password']='123456' dbItem['database']='test' dbItem['charset']='utf8' dbItem['use_unicode']='False' conn = MySQLdb.connect(host=dbItem.get('host'), port=dbItem.get('port', 3306), user=dbItem.get('user'), passwd=dbItem.get('password'), db=dbItem.get('database'), charset=dbItem.get('charset'), use_unicode=dbItem.get('use_unicode')) cursor = conn.cursor() # 初始數據,第一個值爲表名的一部分 list = [('classify', 130, 'classify1'),('content',14,'markdownContent')] insertsql = '''insert into atc_%s(id,data) values(%s, %s)''' "---這裏報錯---" cursor.executemany(insertsql, tuple(list)) conn.close()
-
2.錯誤信息:
TypeError: not all arguments converted during string formatting
-
3.查看
executemany
方法源碼def executemany(self, query, args): del self.messages[:] db = self._get_db() if not args: return charset = db.character_set_name() if isinstance(query, unicode): query = query.encode(charset) "---!!重點就在這裏---" m = insert_values.search(query) if not m: r = 0 for a in args: r = r + self.execute(query, a) return r p = m.start(1) e = m.end(1) qv = m.group(1) try: q = [ qv % db.literal(a) for a in args ] except TypeError, msg: if msg.args[0] in ("not enough arguments for format string", "not all arguments converted"): self.errorhandler(self, ProgrammingError, msg.args[0]) else: self.errorhandler(self, TypeError, msg) except: exc, value, tb = sys.exc_info() del tb self.errorhandler(self, exc, value) r = self._query('\n'.join([query[:p], ',\n'.join(q), query[e:]])) if not self._defer_warnings: self._warning_check() return r
找到關鍵點所在,
m = insert_values.search(query)
import re restr = (r"\svalues\s*" r"(\(((?<!\\)'[^\)]*?\)[^\)]*(?<!\\)?'" r"|[^\(\)]|" r"(?:\([^\)]*\))" r")+\))") # 全部變量 insert_values= re.compile(restr) ... # executemany方法中 m = insert_values.search(query)
這段代碼的意思就是:截取出sql語句中
values
之後的字符串。
我上面的代碼截取到的就應該是:values(%s, %s)
以上代碼有疑惑的同學:傳送門1 傳送門2 -
4.解決方法
問題出在哪裏顯而易見了,executemany
方法中設置參數時沒有截取到values
之前的字段,導致參數個數與%s
個數對不上。將表名和要插入的數據封裝成字典,再進行批量插入即可。修改後的代碼:
import MySQLdb if __name__ == '__main__': dbItem={} ... conn = MySQLdb.connect(host=dbItem.get('host'), port=dbItem.get('port', 3306), user=dbItem.get('user'), passwd=dbItem.get('password'), db=dbItem.get('database'), charset=dbItem.get('charset'), use_unicode=dbItem.get('use_unicode')) cursor = conn.cursor() # 初始數據,第一個值爲表名的一部分 list = [('classify', 130, 'classify1'),('content',14,'markdownContent')] # 封裝成字典數據結構 value_dic = {} for item in list: valList = [] tbName = item[0] if value_dic.has_key(tbName): valList = value_dic.get(tbName) valList.append(item[1:]) value_dic[tbName] = valList # 分數據表批量執行 for tbName,valList in value_dic.items(): insertsql = '''insert into atc_{tbName}(id,data) values(%s, %s)'''.format(tbName=tbName) cursor.executemany(insertsql, tuple(valList)) conn.close()
MySQLdb批量執行sql, TypeError: not all arguments converted during string formatting
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.