繁体   English   中英

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中有多达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变量对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行的crsr变量: response = crsr.fetchall()range(total)possibility每次迭代而变化,它就不会与已经在同一“ for”循环中的其他crsr语句冲突吗?

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

因此,我想知道是否还有其他替代解决方案可供选择,无论哪种解决方案都足够直接有效。

结果集是游标对象的一部分,因此,每当调用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")

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM