微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

sqlite3游标实时更新?

有人可以向我解释一下吗:

import sqlite3

db = sqlite3.connect(':memory:')

db.execute('create table t1 (id integer primary key, val text)')
db.execute('create table t2 (id integer primary key, val text)')

c = db.cursor()
c.execute('insert into t1 values (?, ?)', (1, 'a'))
c.execute('insert into t2 values (?, ?)', (1, 'b'))
c.execute('insert into t1 values (?, ?)', (2, 'c'))
c.execute('insert into t2 values (?, ?)', (2, 'd'))

c.execute('''select t1.id, t1.val, t2.val
             from t1
             left join t2 using (id)
             where t1.id is not null

             union all

             select t2.id, t1.val, t2.val
             from t2
             left join t1 using (id)
             where t2.id is not null
             and t1.id is null

             ''')
for row in c:
    print(row[0])
    if row[0] == 1:
        c2 = db.cursor()
        c2.execute('delete from t1 where id = ?', (row[0],))

如果我注释掉最后三行,输出为:

1
2

但是,如果我取消最后三行的注释,则输出为:

1
2
1

即.第一个游标已被第二个游标中执行的DML结果更新.

这是预期的行为吗?有什么方法可以预防吗?

我正在运行Python 3.6.3(根据Ubuntu 17.10),以防万一.

解决方法:

sqlite会根据需要计算结果行.但这并不总是可能的,因此无法保证.

您永远不要修改当前在另一个查询中读取的任何表. (数据库可能以不明显的方式扫描表,因此即使更改其他行也可能会更改枚举.)

如果打算进行此类修改,则必须在进行更改之前先读取所有行,例如c.fetchall()中的行.另外,也可以分步骤阅读表格,以重新搜索最后一个查询离开的地方,即:

SELECT ... FROM MyTable WHERE ID > :LastID ORDER BY ID LIMIT 1;

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐