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

时间:2013-07-25 14:38:58

标签: python cursor mysql-python

两个方法都返回查询返回项的列表,我在这里错过了什么吗?
他们确实有相同的用法吗?
在性能方面存在差异吗?

5 个答案:

答案 0 :(得分:62)

如果您使用默认光标,MySQLdb.cursors.Cursor整个结果集将存储在客户端(即在Python列表中){{1完成了。

因此,即使您使用

cursor.execute()

你不会减少内存占用。整个结果集已存储在列表中(参见MySQLdb / cursors.py中的for row in cursor: )。

但是,如果您使用SSCursor或SSDictCursor:

self._rows

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

import MySQLdb
import MySQLdb.cursors as cursors

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

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

否则,正如其他人已经说过的那样,cursor = conn.cursor() cursor.execute('SELECT * FROM HUGETABLE') for row in cursor: print(row) cursor.fetchall()基本相同。

答案 1 :(得分:11)

cursor.fetchall()list(cursor)基本相同。不同的选择是不检索列表,而只是循环遍历裸光标对象:

for result in cursor:

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

答案 2 :(得分:4)

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

鉴于上述情况,我建议始终支持list(cursor)超过cursor.fetchall(),以避免在结果集为空的边缘情况下遇到神秘类型错误。

答案 3 :(得分:2)

list(cursor)有效,因为游标是可迭代的;你也可以在循环中使用cursor

for row in cursor:
    # ...

良好的数据库适配器实现将从服务器批量获取行,从而节省了所需的内存占用,因为它不需要在内存中保存完整结果集。 cursor.fetchall() 返回完整列表。

使用list(cursor)而不是cursor.fetchall()几乎没有意义;那么最终效果确实是相同的,但是你浪费了一个改变结果的机会。

答案 4 :(得分:0)

您可以使用列表推导将元组中的项目放入列表中:

conn = mysql.connector.connect()
cursor = conn.cursor()
sql = "SELECT column_name FROM db.table_name;"
cursor.execute(sql)

results = cursor.fetchall()
# bring the first item of the tuple in your results here
item_0_in_result = [_[0] for _ in results]