2013-10-30 34 views
0
cur.executemany(sql, rows) 

我有rows空的迭代器,它會觸發一個錯誤。MySQLdb遊標不支持空迭代器嗎?

如果我做cur.executemany(sql, list(rows))那麼它工作正常。

File "/Enthought/Canopy_64bit/User/lib/python2.7/site-packages/MySQLdb/cursors.py", line 252, in executemany 
    r = self._query('\n'.join([query[:p], ',\n'.join(q), query[e:]])) 
    File "/Enthought/Canopy_64bit/User/lib/python2.7/site-packages/MySQLdb/cursors.py", line 344, in _query 
    rowcount = self._do_query(q) 
    File "/Enthought/Canopy_64bit/User/lib/python2.7/site-packages/MySQLdb/cursors.py", line 308, in _do_query 
    db.query(q) 
_mysql_exceptions.ProgrammingError: (1064, "You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '' at line 1") 

以下是MySQLdb Cursors.py

def executemany(self, query, args): 

     """Execute a multi-row query. 

     query -- string, query to execute on server 

     args 

      Sequence of sequences or mappings, parameters to use with 
      query. 

     Returns long integer rows affected, if any. 

     This method improves performance on multiple-row INSERT and 
     REPLACE. Otherwise it is equivalent to looping over args with 
     execute(). 

     """ 
     del self.messages[:] 
     db = self._get_db() 
     if not args: return 
     if isinstance(query, unicode): 
      query = query.encode(db.unicode_literal.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 (SystemExit, KeyboardInterrupt): 
      raise 
     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 

回答

1

代碼簡短的回答是:不,MySQLdb的不支持將一個空迭代參數executemany

爲什麼不呢?由於行if not args: return。這將處理您通過完全切斷服務器並返回None而不提供參數的情況。空列表,字典,集合或元組的真值爲False,但迭代器的真值始終爲True

如果你在cursors.py中註釋掉那一行,那麼任何空序列或映射都會拋出與空迭代器相同的ER_PARSE_ERROR

爲了使executemany支持空參數,它必須以某種方式測試args是否爲空。如果args是一個迭代器,唯一的方法是調用.next()並觀察結果是否爲StopIteration異常;沒有其他方法可以確定任意迭代器是否爲空。這將是不切實際的,因爲它消耗了迭代器中的項目,並且不適用於任何非迭代器類型,並且毫無意義,因爲executemany不打算在沒有參數的情況下使用。