简体   繁体   English

Python SQLite3 /嵌套cursor.execute

[英]Python SQLite3 / Nested cursor.execute

Consider with this following piece of code: 考虑以下这段代码:

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

Consider with the line: 考虑以下行:

response = crsr.fetchall()

Whenever that there are as much as 10 7 rows in response , the above statement returns a memory error, even on a system with 8 GB of RAM. 每当response中有多达10 7行时,即使在具有8 GB RAM的系统上,上述语句也会返回内存错误。

So, I decided that I would change with the following piece of code: 因此,我决定更改以下代码:

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]

to: 至:

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]

Now that the line: 现在,该行:

response = crsr.fetchone()

makes use of the crsr variable for performing with SQLite3 selection query for every iteration of possibility in range(total) . 利用crsr变量对range(total)每个possibility迭代执行SQLite3选择查询。

There are already other crsr statements in the same 'for' loop: 在相同的“ for”循环中已经存在其他crsr语句:

crsr.execute("UPDATE positions SET result = ? WHERE board = ?", (victor, internal))

with that statement occurring twice, and 该语句出现了两次,并且

crsr.execute("SELECT result FROM positions WHERE board = ?", (external,)) . crsr.execute("SELECT result FROM positions WHERE board = ?", (external,))

with that statement occurring once. 该语句只发生一次。

So, whenever the crsr variable from the line: response = crsr.fetchall() changes with every iteration of possibility in range(total) , will it not conflict with the other crsr statements already in the same 'for' loop? 因此,只要crsr行的crsr变量: response = crsr.fetchall()range(total)possibility每次迭代而变化,它就不会与已经在同一“ for”循环中的其他crsr语句冲突吗?

We cannot create with other cursor variables for executing with different SQLite3 queries, because crsr is defined by using crsr = connection.cursor() for a specific database file, as soon as it is initialized (whichever is spline.db , in this particular case). 我们无法使用其他游标变量来创建以执行不同的SQLite3查询,因为crsr是在特定数据库文件初始化后立即通过使用crsr = connection.cursor()来定义的(在特定情况下为spline.db )。

So, I would like to know that if there are any other alternative solutions available for it whichever are efficient enough quite directly. 因此,我想知道是否还有其他替代解决方案可供选择,无论哪种解决方案都足够直接有效。

A result set is part of the cursor object, so whenever you call execute() , any previous query on the same cursor object is aborted. 结果集是游标对象的一部分,因此,每当调用execute() ,对同一个游标对象的所有先前查询都会中止。 The only way to avoid this is to use fetchall() to read all result rows before the next query is executed. 避免这种情况的唯一方法是在执行下一个查询之前,使用fetchall()读取所有结果行。

To be able to execute multiple simultaneous queries, you must use multiple cursors. 为了能够执行多个同时查询,必须使用多个游标。 Simply call connection.cursor() multiple times. 只需多次调用connection.cursor()


Please note that you must not modify a table that you are still reading from (even if you are using multiple cursors); 请注意,您不得修改仍在读取的表(即使您使用多个游标); changed rows might be skipped or read twice by the read cursor. 更改后的行可能会被读取光标跳过或读取两次。 If you cannot use fetchall() , put the results of the first query into a temporary table: 如果您不能使用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