Python中的cursor.fetchall()vs list(cursor)

2024-04-26 03:32:02 发布

您现在位置:Python中文网/ 问答频道 /正文


Tags: python
3条回答

如果使用的是默认游标,则在完成cursor.execute()时,整个结果集将存储在客户端(即在Python列表中)。

因此,即使你使用

for row in cursor:

内存占用不会减少。整个结果集已经存储在一个列表中(请参见MySQLdb/cursors.py中的self._rows)。

但是,如果使用SSCursor或SSDictCursor:

import MySQLdb
import MySQLdb.cursors as cursors

conn = MySQLdb.connect(..., cursorclass=cursors.SSCursor)

然后结果集存储在服务器mysqld中。现在你可以写了

cursor = conn.cursor()
cursor.execute('SELECT * FROM HUGETABLE')
for row in cursor:
    print(row)

这些行将从服务器中逐个获取,因此不需要Python首先构建一个庞大的元组列表,从而节省内存。

否则,正如其他人已经指出的,cursor.fetchall()list(cursor)本质上是相同的。

使用DictCursor时值得注意的(MySQLdb/PyMySQL特定的)区别是list(cursor)将始终为您提供一个列表,而cursor.fetchall()将为您提供一个列表,除非结果集为空,在这种情况下,它将为您提供一个空元组。在MySQLdb中就是这样,而在较新的PyMySQL中仍然是这样,因为向后兼容的原因,在这里will not be fixed。虽然这个isn't a violation of Python Database API Specification,但它仍然令人惊讶,并且很容易导致类型错误,因为错误地假设结果是列表,而不仅仅是序列

鉴于上述情况,我建议总是倾向于list(cursor)而不是cursor.fetchall(),以避免在结果集为空的边缘情况下被神秘的类型错误捕获。

cursor.fetchall()list(cursor)本质上是相同的。不同的选项是不检索列表,而只是在裸游标对象上循环:

for result in cursor:

如果结果集很大,这可能更有效,因为它不必获取整个结果集并将其全部保存在内存中;它只需增量地获取每个项(或以较小的批处理它们)。

相关问题 更多 >