Yomiage
メニュー

Python実践講座 12:SQLiteとトランザクション

更新 2026/9/27 6:22:11 公開

投稿者: しゅりりん

到達点は、SQLの値を安全に渡し、失敗した更新を取り消すことです。前提は第06・11回です。

検索できる形で保存する

SQLiteは単一ファイルなどにデータを保存できるデータベースです。Python標準ライブラリのsqlite3から使えます。テーブルに型や制約を定義し、SELECTで取得、INSERTで追加、UPDATEで変更、DELETEで削除します。

import sqlite3

db = sqlite3.connect(":memory:")
try:
    db.execute("CREATE TABLE tasks(id INTEGER PRIMARY KEY, title TEXT NOT NULL UNIQUE)")
    db.commit()
    try:
        with db:
            db.execute("INSERT INTO tasks(title) VALUES (?)", ("復習",))
            db.execute("INSERT INTO tasks(title) VALUES (?)", ("復習",))
    except sqlite3.IntegrityError:
        print("重複したため取り消しました")
    print(db.execute("SELECT COUNT(*) FROM tasks").fetchone()[0])
    with db:
        db.execute("INSERT INTO tasks(title) VALUES (?)", ("Python's SQL",))
    for row in db.execute("SELECT id, title FROM tasks ORDER BY id"):
        print(row)
finally:
    db.close()

main.pyで実行すると重複の通知、件数0、その後に追加された一行が出ます。二回の追加を同じトランザクションにまとめたため、二回目が失敗すると最初も取り消されます。この例は3.11以降で使える既定のトランザクション制御を前提にしています。autocommit設定を変える場合は挙動を確認してください。

SQLと値を混ぜない

プレースホルダの疑問符へ、引数タプルで値を渡します。一要素タプルの末尾のカンマを忘れないようにします。f文字列でSQLへ入力を連結すると、SQLインジェクションの原因になります。テーブル名や並び替え列は値のプレースホルダにできないため、許可した候補から選びます。

with dbはトランザクションの確定・取り消しを支援しますが、接続そのものを閉じるものではありません。最後にcloseします。多数の行にはfetchallで全件を保持するか、逐次処理するかも選びます。

インデックスは検索を助ける代わりに、書き込み費用と保存領域を増やします。外部キーを使う場合、接続で PRAGMA foreign_keys = ON を有効にすることも確認します。複数接続での同時更新にはロック待ちと再試行の設計が必要です。

練習と解答

練習:最初のINSERTの直後にcommitしてしまうと、重複時の件数はどうなりますか。

解答:最初の一行は確定済みなので残ります。トランザクションの境界は、何を「全部成功か全部失敗」にしたいかから決めます。

公式資料

sqlite3とSQLiteのトランザクションが参照先です。


Python全20回の目次 | 前の回 | 次の回

このブラウザでは Web Speech API が利用できません。

1 / 16 · 停止中