Python 无法阻止 SQLite3 中的自动提交
Cannot prevent auto-commit in SQLite3 for Python
我对 python 的内置模块 sqlite3 的行为感到困惑。
无论我是否评论 out/in 包含提交语句的行,以下代码都会打印出插入的数据。怎么可能?
我阅读 python 文档的理解是,虽然 sqlite3 的底层 C 库默认启用了自动提交,但 python 绑定没有。相反,我必须将 isolation_level=None
添加到 connect() 调用以启用自动提交。我问这个是因为我想关闭自动提交但找不到这样做的方法。
我的Python版本是3.9.2,由于sqlite3是内置模块,我想模块版本也是3.9.2。
import sqlite3
import os
if os.path.exists("dummy.db"):
os.system('rm dummy.db')
assert not os.path.exists("dummy.db") #ensure dummy.db is a new db every run
# Write
c = sqlite3.connect("dummy.db")
ddl = '''--sql
CREATE TABLE foo_table (foo INTEGER, bar INTEGER, foobar INTEGER);
'''
c.execute(ddl)
ddl = '''--sql
INSERT INTO foo_table VALUES(1,2,3);
'''
c.execute(ddl)
#c.commit()
c.close()
# Read
c = sqlite3.connect("dummy.db")
ddl = 'SELECT * FROM foo_table'
for row in c.execute(ddl):
print(row)
输出
>>(1, 2, 3)
SQLite 中带有“--sql”行的命令在脚本模式下 运行,默认情况下似乎是 auto-commit,而不是执行单个SQL 命令,默认使用手动提交模式进行插入、更新、删除等。如果将命令从 --sql
更改为标准 SQL 命令,则插入将推迟到显式提交被执行。
con = sqlite3.connect("dummy.db")
cursor = con.cursor()
# auto-commit mode for CREATE/ALTER/DROP
cursor.execute('CREATE TABLE foo_table (foo INTEGER, bar INTEGER, foobar INTEGER)')
# Manual commit mode (the default) for INSERT, UPDATE, DELETE
cursor.execute('INSERT INTO foo_table VALUES(1,2,3)')
# uncomment commit below and the row will be inserted
#con.commit()
con.close()
# Read
con = sqlite3.connect("dummy.db")
cursor = con.cursor()
cursor.execute('SELECT * FROM foo_table')
result = cursor.fetchall()
print("rows=", len(result), sep='')
for row in result:
print(row)
输出:
rows=0
如果要为 SQL 命令启用自动提交模式,请将 isolation_level 设置为 None。
con = sqlite3.connect("dummy.db", isolation_level=None)
输出:
rows=1
(1, 2, 3)
要获得更多 fine-grain 控制,您可以将 transactions 与 BEGIN、COMMIT 和 ROLLBACK 命令一起使用。如果调用回滚或简单地关闭连接则不提交插入。
cursor.execute("begin")
cursor.execute("INSERT...")
cursor.execute("rollback")
我对 python 的内置模块 sqlite3 的行为感到困惑。 无论我是否评论 out/in 包含提交语句的行,以下代码都会打印出插入的数据。怎么可能?
我阅读 python 文档的理解是,虽然 sqlite3 的底层 C 库默认启用了自动提交,但 python 绑定没有。相反,我必须将 isolation_level=None
添加到 connect() 调用以启用自动提交。我问这个是因为我想关闭自动提交但找不到这样做的方法。
我的Python版本是3.9.2,由于sqlite3是内置模块,我想模块版本也是3.9.2。
import sqlite3
import os
if os.path.exists("dummy.db"):
os.system('rm dummy.db')
assert not os.path.exists("dummy.db") #ensure dummy.db is a new db every run
# Write
c = sqlite3.connect("dummy.db")
ddl = '''--sql
CREATE TABLE foo_table (foo INTEGER, bar INTEGER, foobar INTEGER);
'''
c.execute(ddl)
ddl = '''--sql
INSERT INTO foo_table VALUES(1,2,3);
'''
c.execute(ddl)
#c.commit()
c.close()
# Read
c = sqlite3.connect("dummy.db")
ddl = 'SELECT * FROM foo_table'
for row in c.execute(ddl):
print(row)
输出
>>(1, 2, 3)
SQLite 中带有“--sql”行的命令在脚本模式下 运行,默认情况下似乎是 auto-commit,而不是执行单个SQL 命令,默认使用手动提交模式进行插入、更新、删除等。如果将命令从 --sql
更改为标准 SQL 命令,则插入将推迟到显式提交被执行。
con = sqlite3.connect("dummy.db")
cursor = con.cursor()
# auto-commit mode for CREATE/ALTER/DROP
cursor.execute('CREATE TABLE foo_table (foo INTEGER, bar INTEGER, foobar INTEGER)')
# Manual commit mode (the default) for INSERT, UPDATE, DELETE
cursor.execute('INSERT INTO foo_table VALUES(1,2,3)')
# uncomment commit below and the row will be inserted
#con.commit()
con.close()
# Read
con = sqlite3.connect("dummy.db")
cursor = con.cursor()
cursor.execute('SELECT * FROM foo_table')
result = cursor.fetchall()
print("rows=", len(result), sep='')
for row in result:
print(row)
输出:
rows=0
如果要为 SQL 命令启用自动提交模式,请将 isolation_level 设置为 None。
con = sqlite3.connect("dummy.db", isolation_level=None)
输出:
rows=1
(1, 2, 3)
要获得更多 fine-grain 控制,您可以将 transactions 与 BEGIN、COMMIT 和 ROLLBACK 命令一起使用。如果调用回滚或简单地关闭连接则不提交插入。
cursor.execute("begin")
cursor.execute("INSERT...")
cursor.execute("rollback")