我正在开发一个应用程序,在该应用程序中,我遍历表中的许多(1,000,000+)行,同时插入新行并更新现有行。需要select语句产生表中的每一行(最初执行select时存在的行)一次,并且绝不会产生在执行select后插入的行。我宁愿不将所有行加载到内存中(这需要很长时间和很多内存 - 我试过了)。SQLite:选择受后续插入影响的结果
我开发了一个小Python示例,演示了SQLite显然不会从长时间运行的选择中隔离插入(并假定更新和删除)。我无法在SQLite文档中找到任何明确提及此行为的地方,但是我发现了几个提到插入失败的链接(可能在SQLite的早期版本中?),它不在我的示例中。
import sqlite3
def select_affected_by_insert():
# select from and simultaneously modify same table
cn = sqlite3.connect(':memory:')
cn.execute("CREATE TABLE demo (v INTEGER PRIMARY KEY)")
n = 5
values = [[v] for v in range(n)]
cn.executemany('INSERT INTO demo VALUES (?)', values)
for (v,) in cn.execute('SELECT v FROM demo'):
with cn:
# insert in transaction
cn.execute('INSERT INTO demo VALUES (?)', [n + v])
print v, n + v
assert v < n, 'got more rows than expected!'
if __name__ == '__main__':
select_affected_by_insert()
的SQLite 3.6.12
的Python 2.6.4
是否有更好的方法来解决这个比数据复制到一个单独的(临时)表,并从那里选择?
说明:我忽略说我需要在循环内部进行提交。该过程可能会中断,部分完成的工作必须提交,以便在下一个运行时不需要重做。
你有没有发现这样做的一个很好的方式
@StavrosKorokithakis我最终在文件中缓存了SELECT的结果。 WAL模式,Doug Currie在下面提到,也可能是一个可行的解决方案,但是对于我的特殊情况来说,权衡并不值得。 – millerdev
啊,这听起来不是最理想的,但你能做什么...感谢您的帮助。 –