考虑以下这段代码:
for count in range(28, -1, -1):
crsr.execute("SELECT board, win1, win2 FROM positions WHERE balls = ?", (count,))
response = crsr.fetchall()
print count, len(response)
for possibility in response:
internal = possibility[0]
player = count & 1
victor = 1 - player
opponent = 2 - player
victory = possibility[opponent]
if victory:
crsr.execute("UPDATE positions SET result = ? WHERE board = ?", (victor, internal))
else:
subsequent = derive((internal, count))
for derived in subsequent:
external = reduce(derived[0])
crsr.execute("SELECT result FROM positions WHERE board = ?", (external,))
colour = crsr.fetchall()
if colour[0][0] == player:
victor = player
break
crsr.execute("UPDATE positions SET result = ? WHERE board = ?", (victor, internal))
考虑一下:
response = crsr.fetchall()
每当response
中有多达10个 7 行时,上述语句就会返回内存错误,即使在具有8 GB RAM的系统上也是如此。
所以,我决定用以下代码改变:
for count in range(28, -1, -1):
crsr.execute("SELECT board, win1, win2 FROM positions WHERE balls = ?", (count,))
response = crsr.fetchall()
print count, len(response)
for possibility in response:
internal = possibility[0]
为:
for count in range(28, -1, -1):
crsr.execute("SELECT COUNT(board) FROM positions WHERE balls = ?", (count,))
sum = crsr.fetchall()
total = sum[0][0]
print count, total
crsr.execute("SELECT board, win1, win2 FROM positions WHERE balls = ?", (count,))
for possibility in range(total):
response = crsr.fetchone()
internal = response[0]
现在就行:
response = crsr.fetchone()
利用crsr
变量为possibility
中range(total)
的每次迭代执行SQLite3选择查询。
在'for'循环中已经存在其他crsr
个语句:
crsr.execute("UPDATE positions SET result = ? WHERE board = ?", (victor, internal))
该声明发生两次,
crsr.execute("SELECT result FROM positions WHERE board = ?", (external,))
。
该声明发生一次。
因此,只要crsr
行中的response = crsr.fetchall()
变量随着possibility
中range(total)
的每次迭代而变化,它就不会与其他crsr
冲突}语句已经在同一个'for'循环中?
我们无法使用其他游标变量创建用于执行不同的SQLite3查询,因为crsr是通过使用crsr = connection.cursor()
为特定数据库文件定义的,只要它被初始化(以spline.db
为准),这个特例)。
所以,我想知道,如果有任何其他替代解决方案可供选择,那么非常有效。
答案 0 :(得分:1)
结果集是游标对象的一部分,因此无论何时调用execute()
,都会中止对同一游标对象的任何先前查询。避免这种情况的唯一方法是在执行下一个查询之前使用fetchall()
读取所有结果行。
为了能够执行多个同时查询,您必须使用多个游标。只需多次致电connection.cursor()
。
请注意,您不得修改您仍在阅读的表格(即使您使用的是多个游标);读取光标可能会跳过或读取两次更改的行。如果您无法使用fetchall()
,请将第一个查询的结果放入临时表中:
crsr1.execute("CREATE TEMP TABLE temp_pos(board, win1, win2)")
for count in ...:
crsr1.execute("INSERT INTO temp_pos SELECT board, win1, win2 ...")
crsr1.execute("SELECT board, win1, win2 FROM temp_pos")
for row in crsr1:
if ...:
crsr2.execute("UPDATE positions ...")
else:
crsr2.execute("SELECT ... FROM positions ...")
...
crsr1.execute("DELETE FROM temp_pos")
crsr1.execute("DROP TABLE temp_pos")