我有以下代码
cur = db.cursor(cursors.SSDictCursor)
cur.execute("SELECT * FROM large_table")
result_count = cur.rowcount
print result_count
这会打印数字18446744073709551615
,这显然是错误的。如果我删除cursors.SSDictCursor
,则会显示正确的号码。谁能告诉我如何在保留SSDictCursor的同时获得返回的记录数?
答案 0 :(得分:5)
要获取SSDictCursor
或SSCursor
返回的记录数,您唯一的选择是:
获取整个结果并使用len()
对其进行统计,这首先违背了使用SSDictCursor
或SSCursor
的目的;
在迭代它们时自己计算行数,这意味着在结束之前你不会知道计数(不太可能是实际的);或者,
运行其他单独的COUNT(*)
查询。
我强烈推荐第三种选择。如果您所做的只是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()
,允许服务器在获取完成之前开始传输数据。