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

Joh*_*ohn 7 python mysql-python

我有以下代码

cur = db.cursor(cursors.SSDictCursor)
cur.execute("SELECT * FROM large_table")
result_count = cur.rowcount
print result_count
Run Code Online (Sandbox Code Playgroud)

这打印出18446744073709551615明显错误的数字.如果我删除了cursors.SSDictCursor正确的号码显示.谁能告诉我如何在保持SSDictCursor的同时获得返回的记录数量?

Air*_*Air 5

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

  1. 获取整个结果并使用它来计算len(),这会使用SSDictCursorSSCursor首先失败;

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

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

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


顺便说一句,你看到的返回值是那种正确的; 至少,就MySQL C API而言.

根据PEP 249中定义的Python DB API,如果接口无法确定最后一个操作的rowcount,则rowcount属性为-1.@glglgl解释了为什么无法在答案中确定行数:

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

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

>>> from ctypes import c_ulonglong
>>> n = c_ulonglong(-1)
>>> n.value
18446744073709551615L
Run Code Online (Sandbox Code Playgroud)

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

>>> -1 & 0xFFFFFFFFFFFFFFFF
18446744073709551615L
Run Code Online (Sandbox Code Playgroud)

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


glg*_*lgl 3

对于 a SSDictCursor,该值只能读取。确定光标何时用完。

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