我很难理解python的sqlite3模块的游标对象的行为。据我所知,游标对象的行为就像迭代器在数据结构上保持一个“视图”。现在,我认为这种行为有两种方式:
1)执行时,与SELECT *语句匹配的数据库状态与期货变化保持分离。
2)执行时,匹配SELECT *语句的数据库状态只是底层可变数据的视图。也就是说,一旦执行了for ... in cur行,就会发生延迟计算。
但显然也不是这样,请看下面的脚本和输出。在执行此脚本时,为什么没有将UPDATE命令合并到游标中,而INSERT是?总是使用result = list(cur.execute(...))更好吗
#!/usr/bin/env python3
import sqlite3
con = sqlite3.connect("db.sqlite")
con.execute("""CREATE TABLE IF NOT EXISTS `table` (
`id` INTEGER UNIQUE,
`name` TEXT,
PRIMARY KEY(`id`)
);""")
con.execute("INSERT INTO `table` VALUES (1, 'smith')")
con.execute("INSERT INTO `table` VALUES (2, 'mia')")
con.commit()
print("in db: (1, smith), (2, mia)")
### Querying the table
cur = con.cursor()
cur.execute("SELECT * FROM `table`")
### Changing the table
print("altering table: add (3, kim), change (1, smith) to (1, james)")
con.execute("UPDATE `table` SET name='james' where id=1")
con.execute("INSERT INTO `table` VALUES (3, 'kim')")
con.commit()
print()
print("1) expect immutable: (1, smith), (2, mia)")
print("2) expect mutable: (1, james), (2, mia), (3, kim)")
print()
print("But got: ")
for row in cur: print(row)输出
in db: (1, smith), (2, mia)
altering table: add (3, kim), change (1, smith) to (1, james)
1) expect immutable: (1, smith), (2, mia)
2) expect mutable: (1, james), (2, mia), (3, kim)
But got:
(1, 'smith')
(2, 'mia')
(3, 'kim')平台
发布于 2019-03-01 14:36:18
不幸的是,这是SQLite的工作方式。来自SQLite中的分离
..。但是,在SELECT语句运行时发生的更改呢?如果启动了SELECT语句,sqlite3_step()接口执行了大约一半的输出,那么一些UPDATE语句将由修改SELECT语句读取的表的应用程序运行,然后调用sqlite3_step()来完成SELECT语句?SELECT语句的后续步骤会看到更新所做的更改吗?答案是这种行为是没有定义的..。因此,开发人员应该努力避免编写应用程序来假设在这种情况下会发生什么。
这意味着SQLite可以在到同一个数据库的不同连接之间提供一些隔离(注意,只有一个应该写),但是您不应该试图修改数据库,至少是要读取的表,在SELECT的开始和结束之间。
https://stackoverflow.com/questions/54946508
复制相似问题