Python MysqlDB使用cursor.rowcount和SSDictCursor返回错误计数

时间:2012-02-01 15:14:27

标签: python mysql-python

我有以下代码

cur = db.cursor(cursors.SSDictCursor)
cur.execute("SELECT * FROM large_table")
result_count = cur.rowcount
print result_count

这会打印数字18446744073709551615,这显然是错误的。如果我删除cursors.SSDictCursor,则会显示正确的号码。谁能告诉我如何在保留SSDictCursor的同时获得返回的记录数?

2 个答案:

答案 0 :(得分:5)

要获取SSDictCursorSSCursor返回的记录数,您唯一的选择是:

  1. 获取整个结果并使用len()对其进行统计,这首先违背了使用SSDictCursorSSCursor的目的;

  2. 在迭代它们时自己计算行数,这意味着在结束之前你不会知道计数(不太可能是实际的);或者,

  3. 运行其他单独的COUNT(*)查询。

  4. 我强烈推荐第三种选择。如果您所做的只是SELECT COUNT(*) FROM table;,那就太快了。对于一些更复杂的查询来说会更慢,但是通过适当的索引,对于大多数用途来说它应该仍然足够快。


    顺便说一下,你看到的返回值有点正确;至少,就MySQL C API而言。

    根据PEP 249中定义的Python DB API,the rowcount attribute is -1 if the rowcount of the last operation cannot be determined by the interface。 @glglgl解释了为什么无法在答案中确定行数:

      

    在内部,SSDictCursor使用mysql_use_result(),允许服务器在获取完成之前开始传输数据。

    换句话说,服务器不知道它最终要获取多少行。执行查询时,MySQLdb会将mysql_affected_rows()的返回值存储在游标的rowcount属性中。因为计数是不确定的,所以此函数返回-1作为无符号长整数(my_ulonglong),这是一种在标准库的ctypes模块中可用的数字类型:

    >>> from ctypes import c_ulonglong
    >>> n = c_ulonglong(-1)
    >>> n.value
    18446744073709551615L
    

    当你知道你将永远处理64位无符号整数时,ctypes的快速替代方法是:

    >>> -1 & 0xFFFFFFFFFFFFFFFF
    18446744073709551615L
    

    如果MySQLdb检查了此返回值并给出了您希望看到的有符号整数,那将会很棒。但不幸的是,它没有。

答案 1 :(得分:3)

使用SSDictCursor时,只能读取此值。光标用完时确定。

在内部,SSDictCursor使用mysql_use_result(),允许服务器在获取完成之前开始传输数据。