两个方法都返回查询返回项的列表,我在这里错过了什么吗?
他们确实有相同的用法吗?
在性能方面存在差异吗?
答案 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]