两种方法都返回查询返回项的列表,我在这里遗漏了什么,或者它们确实有相同的用法吗?
性能方面有什么不同吗?
如果您使用默认游标 a MySQLdb.cursors.Cursor
,则整个结果集将在完成时存储在客户端(即 Python 列表中)cursor.execute()
。
因此,即使您使用
for row in cursor:
您不会减少内存占用。整个结果集已经存储在一个列表中(参见self._rows
MySQLdb/cursors.py)。
但是,如果您使用 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)
本质上是相同的。
cursor.fetchall()
并且list(cursor)
本质上是一样的。不同的选项是不检索列表,而只是遍历裸游标对象:
for result in cursor:
如果结果集很大,这可能会更有效,因为它不必获取整个结果集并将其全部保存在内存中;它可以逐步获取每个项目(或以较小的批次进行批量处理)。
list(cursor)
有效,因为游标是可迭代的;您也可以cursor
在循环中使用:
for row in cursor:
# ...
一个好的数据库适配器实现将从服务器批量获取行,节省所需的内存占用,因为它不需要在内存中保存完整的结果集。cursor.fetchall()
必须返回完整列表。
使用list(cursor)
over没有什么意义cursor.fetchall()
;最终效果确实是一样的,但是您浪费了一个流式传输结果的机会。
使用 a 时值得注意的一个(MySQLdb/PyMySQL 特有的)区别DictCursor
是它list(cursor)
总是给你一个列表,而cursor.fetchall()
给你一个列表,除非结果集为空,在这种情况下它给你一个空元组。在 MySQLdb 中就是这种情况,在较新的PyMySQL中仍然是这种情况,由于向后兼容的原因,它不会被修复。虽然这并不违反 Python 数据库 API 规范,但它仍然令人惊讶,并且很容易导致由于错误地假设结果是一个列表而导致的类型错误,而不仅仅是一个序列。
鉴于上述情况,我建议始终支持,以避免list(cursor)
在cursor.fetchall()
结果集为空的边缘情况下被神秘的类型错误所吸引。
您可以使用列表推导将元组中的项目放入列表中:
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]