是否需要sqlite3 fetchall?

4m1*_*4j1 6 python sql sqlite

我刚开始使用sqlite3和python.我想知道之间的区别:

cursor = db.execute("SELECT customer FROM table")
    for row in cursor:
              print row[0]
Run Code Online (Sandbox Code Playgroud)

cursor = db.execute("SELECT customer FROM table")
    for row in cursor.fetchall():
              print row[0]
Run Code Online (Sandbox Code Playgroud)

除了cursor<type 'sqlite3.Cursor'>cursor.fetchall()<type 'list'>,它们都有相同的结果.

是否存在差异,偏好或特定情况,其中一个比另一个更优先?

CL.*_*CL. 10

fetchall() 将所有记录读入内存,然后返回该列表.

迭代游标本身时,只在需要时读取行.当您拥有大量数据并且可以逐个处理行时,这会更有效.

  • 我认为重要的是要考虑到在运行选择查询时可能会并行写入数据库。考虑一下如果您想要更新正在迭代的某些行或者如果有另一个进程或线程可能正在执行此类更新,会发生什么情况。如果您迭代游标本身,您的查询可能会突然停止返回它应该具有的行,但如果您将所有行提取到内存中,您将获得该时间窗口内的行,而无需修改,无论好坏。 (2认同)
  • @DavidOldford SQLite 总是使用[可序列化事务](https://www.sqlite.org/transactional.html);那不可能发生。 (2认同)

Pau*_* Bu 7

主要区别正是对 的调用fetchall()。通过发出fetchall(),它将返回一个list对象,其中填充了初始查询中剩余的所有元素(如果还没有得到任何元素,则为所有元素)。这有几个缺点:

  1. 增加内存使用量:通过将所有查询的元素存储在一个列表中,这可能是巨大的
  2. 糟糕的性能:如果有很多元素,填充列表可能会很慢
  3. 进程终止:如果它是一个巨大的查询,那么您的程序可能会因内存不足而崩溃。

当您改为使用cursor迭代器 ( for e in cursor:) 时,您会延迟获取查询的行。这意味着,只有在程序需要时才一一返回。

当然,您的两个代码片段的输出是相同的,但在内部使用fetchall()和 using only之间存在巨大的性能缺陷cursor

希望这可以帮助!