MySQLdb游标不支持空迭代器吗?

时间:2022-09-22 12:26:30
cur.executemany(sql, rows)

I have rows as empty iterator, it triggers an error.

我有行作为空迭代器,它触发一个错误。

If I do cur.executemany(sql, list(rows)) then it works fine.

如果我执行cur.executemany(sql、list(行)),那么它就可以正常工作了。

 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")

The following is the code for MySQLdb Cursors.py

下面是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 个解决方案

#1


1  

The short answer is: No, MySQLdb does not support passing an empty iterator argument to executemany.

简短的回答是:不,MySQLdb不支持将空迭代器参数传递给executemany。

Why not? Because of the line if not args: return. This handles the case where you provide no parameters by cutting the server out entirely and returning None. The truth value of an empty list, dict, set, or tuple is False, but the truth value of an iterator is always True.

为什么不呢?因为这条线如果不是args:返回。这将处理您不提供参数的情况,将服务器完全删除,而不返回任何参数。空列表、命令、集合或元组的真值是假的,但迭代器的真值总是正确的。

If you comment out that line in cursors.py, then any empty sequence or mapping will throw the same ER_PARSE_ERROR as the empty iterator.

如果你在游标中注释掉这一行。py,然后任何空序列或映射都会抛出相同的ER_PARSE_ERROR作为空迭代器。

In order for executemany to support empty arguments, it has to test whether args is empty somehow. If args is an iterator, the only way to do this is to call .next() and observe whether the result is a StopIteration exception; there's no other way to determine whether an arbitrary iterator is empty. This would be impractical because it consumes an item from the iterator and doesn't work for any non-iterator type, and pointless because executemany is not intended to be used without parameters in the first place.

为了让executemany支持空参数,它必须测试args是否为空。如果args是一个迭代器,那么唯一的方法就是调用.next(),并观察结果是否为StopIteration异常;没有其他方法来确定任意迭代器是否为空。这是不切实际的,因为它从迭代器中消耗了一个项目,并且对任何非迭代器类型都不起作用,而且没有意义,因为executemany最初并不打算使用参数。

#1


1  

The short answer is: No, MySQLdb does not support passing an empty iterator argument to executemany.

简短的回答是:不,MySQLdb不支持将空迭代器参数传递给executemany。

Why not? Because of the line if not args: return. This handles the case where you provide no parameters by cutting the server out entirely and returning None. The truth value of an empty list, dict, set, or tuple is False, but the truth value of an iterator is always True.

为什么不呢?因为这条线如果不是args:返回。这将处理您不提供参数的情况,将服务器完全删除,而不返回任何参数。空列表、命令、集合或元组的真值是假的,但迭代器的真值总是正确的。

If you comment out that line in cursors.py, then any empty sequence or mapping will throw the same ER_PARSE_ERROR as the empty iterator.

如果你在游标中注释掉这一行。py,然后任何空序列或映射都会抛出相同的ER_PARSE_ERROR作为空迭代器。

In order for executemany to support empty arguments, it has to test whether args is empty somehow. If args is an iterator, the only way to do this is to call .next() and observe whether the result is a StopIteration exception; there's no other way to determine whether an arbitrary iterator is empty. This would be impractical because it consumes an item from the iterator and doesn't work for any non-iterator type, and pointless because executemany is not intended to be used without parameters in the first place.

为了让executemany支持空参数,它必须测试args是否为空。如果args是一个迭代器,那么唯一的方法就是调用.next(),并观察结果是否为StopIteration异常;没有其他方法来确定任意迭代器是否为空。这是不切实际的,因为它从迭代器中消耗了一个项目,并且对任何非迭代器类型都不起作用,而且没有意义,因为executemany最初并不打算使用参数。