我今天刚与一些同事就python的db-api fetchone与fetchmany vs fetchall进行了讨论。
我确定每个用例的用例取决于我正在使用的db-api的实现,但一般来说fetchone vs fetchmany vs fetchall的用例是什么?
换句话说是以下等价物?或者其中一个比其他的更受欢迎?如果是这样的话?
cursor.execute("SELECT id, name FROM `table`")
for i in xrange(cursor.rowcount):
id, name = cursor.fetchone()
print id, name
cursor.execute("SELECT id, name FROM `table`")
result = cursor.fetchmany()
while result:
for id, name in result:
print id, name
result = cursor.fetchmany()
cursor.execute("SELECT id, name FROM `table`")
for id, name in cursor.fetchall():
print id, name
答案 0 :(得分:14)
我认为这确实取决于实现,但您可以通过查看MySQLdb源来了解差异。根据选项,mysqldb fetch *保留内存或服务器端的当前行集,因此fetchmany vs fetchone在这里有一些灵活性,可以知道在(python)内存中保留什么以及保留数据库服务器端的内容。
PEP 249没有提供太多细节,所以我想这是根据数据库优化的东西,而确切的语义是实现定义的。
答案 1 :(得分:7)
这些是特定于实现的。
将从表中获得所有结果。当表的大小很小时,这将更好地工作。如果表大小较大,则在这些情况下fetchall将失败。
将使用大部分内存。
如果在网络上完成查询,将导致一些问题。
fetchmany将只获得所需的结果数量。您可以产生结果和过程。 fetchmany的简单实现。
while True:
results = cursor.fetchmany(arraysize)
if not results:
break
for result in results:
yield result
答案 2 :(得分:4)
fetchone()
获取查询结果集的下一行,返回一个元组,如果没有更多数据可用,则返回None:
>>> cur.execute("SELECT * FROM test WHERE id = %s", (3,))
>>> cur.fetchone()
(3, 42, 'bar')
如果先前对execute *()的调用未产生任何结果集或尚未发出任何调用,则会引发ProgrammingError。
fetchmany([size = cursor.arraysize])
获取查询结果的下一组行,返回元组列表。没有更多行可用时,将返回一个空列表。
每个调用要获取的行数由参数指定。如果未指定,则游标的arraysize决定要提取的行数。该方法应尝试获取size参数指示的尽可能多的行。如果由于指定的行数不可用而无法执行此操作,则可能会返回较少的行:
>>> cur.execute("SELECT * FROM test;")
>>> cur.fetchmany(2)
[(1, 100, "abc'def"), (2, None, 'dada')]
>>> cur.fetchmany(2)
[(3, 42, 'bar')]
>>> cur.fetchmany(2)
[]
如果先前对execute *()的调用未产生任何结果集或尚未发出任何调用,则会引发ProgrammingError。
请注意,size参数涉及性能方面的考虑。为了获得最佳性能,通常最好使用arraysize属性。如果使用size参数,则最好从一个fetchmany()调用到下一个调用保持相同的值。
列表项
fetchall()
获取查询结果的所有(剩余)行,并将它们作为元组列表返回。如果没有更多要提取的记录,则返回一个空列表。
>>> cur.execute("SELECT * FROM test;")
>>> cur.fetchall()
[(1, 100, "abc'def"), (2, None, 'dada'), (3, 42, 'bar')]
如果先前对execute *()的调用未产生任何结果集或尚未发出任何调用,则会引发ProgrammingError。