8

如果我想创建一个表并在另一个表中插入一个新条目,可以在 sqlite 模块中将其设为原子吗?

参考http://docs.python.org/2/library/sqlite3.html上的文档:

默认情况下,sqlite3 模块在数据修改语言 (DML) 语句(即 INSERT/UPDATE/DELETE/REPLACE)之前隐式打开事务,并在非 DML、非查询语句(即除了 SELECT 或之前所提)。

因此,如果您在事务中并发出诸如 CREATE TABLE ...、VACUUM、PRAGMA 之类的命令,则 sqlite3 模块将在执行该命令之前隐式提交。这样做有两个原因。首先是其中一些命令在事务中不起作用。另一个原因是 sqlite3 需要跟踪事务状态(如果事务处于活动状态)。

我不确定这第二段是否适用于自动启动的事务或手动和自动事务。

Sqlite 文档http://www.sqlite.org/lang_transaction.html告诉我们,手动事务在明确提交之前不会提交:

可以使用 BEGIN 命令手动启动事务。此类事务通常持续到下一个 COMMIT 或 ROLLBACK 命令。

所以假设我们有这样的事情:

con = sqlite3.connect(fdb) 
cur = con.cursor()

sql = 'begin transaciton'
cur.execute(sql)    

sql = 'CREATE TABLE some-table ...
cur.execute(sql)

# *** is there an implicit commit at this point ?! ***

sql = 'INSERT INTO  another-table ...
cur.execute(sql)

con.commit()

这会是原子的,还是 python sqlite 在create table语句之后进行提交?有没有办法让它成为原子的?

4

2 回答 2

6

您不能以原子方式执行此操作。COMMIT每当您执行语句时, Python SQLite 库都会隐式发出 a CREATE TABLE ..,因为 SQLite 不支持CREATE TABLE ..在事务处于活动状态时执行该语句。

您可以通过在 python 解释器和sqlite3命令行工具中打开数据库来测试它。发出CREATE TABLE ..语句后,您可以.schemasqlite3命令行工具中运行命令并查看该语句的结果。

请注意,这意味着您在语句之前在事务中所做的任何事情CREATE TABLE ..也将被提交。换一种方式来看,CREATE TABLE ..语句首先提交,然后开始一个全新的事务。

于 2012-11-30T10:20:03.810 回答
3

Python SQLite3 库即使在不需要的地方也会插入自动提交。

要使您的整个事务原子化,请使用任何其他 Python SQLite 包装器,例如APSW

于 2012-11-30T12:04:34.590 回答