8

テーブルを作成し、新しいエントリを別のテーブルに挿入したい場合、これを sqlite モジュールでアトミックにすることはできますか?

http://docs.python.org/2/library/sqlite3.htmlのドキュメントを参照:

デフォルトでは、sqlite3 モジュールは、データ変更言語 (DML) ステートメント (つまり、INSERT/UPDATE/DELETE/REPLACE) の前に暗黙的にトランザクションを開き、非 DML、非クエリ ステートメント (つまり、SELECT またはステートメント以外のもの) の前に暗黙的にトランザクションをコミットします。前述の)。

したがって、トランザクション内で CREATE TABLE ...、VACUUM、PRAGMA などのコマンドを発行すると、sqlite3 モジュールはそのコマンドを実行する前に暗黙的にコミットします。そうする理由は2つあります。1 つ目は、これらのコマンドの一部がトランザクション内で機能しないことです。もう 1 つの理由は、sqlite3 がトランザクションの状態を追跡する必要があるためです (トランザクションがアクティブかどうか)。

この 2 番目の段落が、自動的に開始されたトランザクションに適用されるのか、それとも手動と自動のトランザクションの両方に適用されるのかはわかりません。

Sqlite ドキュメントhttp://www.sqlite.org/lang_transaction.htmlは、明示的な COMMIT まで手動トランザクションがコミットされないことを示しています。

トランザクションは、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

これをアトミックに行うことはできません。SQLiteはトランザクションがアクティブな間はステートメントの実行をサポートしていないため、PythonSQLiteライブラリはステートメントCOMMITを実行するたびに暗黙的にを発行します。CREATE TABLE ..CREATE TABLE ..

sqlite3これをテストするには、Pythonインタープリターとコマンドラインツールの両方でデータベースを開きます。ステートメントを発行するとすぐに、コマンドラインツールでコマンドCREATE TABLE ..を実行して、そのステートメントの結果を確認できます。.schemasqlite3

これは、ステートメントのにトランザクションで行ったすべてのこともコミットされることを意味することに注意してください。CREATE TABLE ..別の見方をすると、CREATE TABLE ..ステートメントは最初にコミットし、次に完全に新しいトランザクションを開始します。

于 2012-11-30T10:20:03.810 に答える
3

Python SQLite3ライブラリは、必要がない場合でも自動コミットを挿入します。

トランザクション全体をアトミックにするには、APSWなどの他のPythonSQLiteラッパーを使用します。

于 2012-11-30T12:04:34.590 に答える