Python SQLite3 / 嵌套 cursor.execute

Python SQLite3 / Nested cursor.execute

考虑以下这段代码:

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 中有多达 107 行时,上述语句 returns 内存错误,即使在具有 8 GB 内存。

因此,我决定使用以下代码进行更改:

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 变量对 range(total)possibility 的每次迭代执行 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() 随着 range(total)possibility 的每次迭代而变化时,它不会与其他 [= 冲突吗? 18=] 个语句已经在同一个 'for' 循环中?

我们无法使用其他游标变量创建用于执行不同的 SQLite3 查询,因为 crsr 是通过使用 crsr = connection.cursor() 为特定数据库文件定义的,一旦它被初始化(以 spline.db 为准,在这种特殊情况下)。

所以,我想知道是否有任何其他可用的替代解决方案,无论哪个都足够直接。

结果集是游标对象的一部分,因此无论何时调用 execute(),之前对同一游标对象的任何查询都将中止。避免这种情况的唯一方法是在执行下一个查询之前使用 fetchall() 读取所有结果行。

为了能够同时执行多个查询,您必须使用多个游标。只需多次调用 connection.cursor()


请注意,您不得修改仍在阅读的 table(即使您正在使用多个游标);已更改的行可能会被读取游标跳过或读取两次。如果不能使用fetchall(),将第一个查询的结果放入临时的table:

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")