SQLiteを学んでいこうという連載の25回目です。前回の記事はこちらになります。
前回は、Pythonから使用する場合のエラー処理の事例をご紹介しました。Pythonはプログラム言語なので、結果によって色々な処理を切り替えることができます。
今回はPythonから使用する場合のトランザクション処理です。
Pythonとトランザクション処理
それではさっそくPythonでのトランザクション処理例を見ていきましょう。
まずはAnaconda PromptからSQLte3を起動して、データベースファイルを新規作成します。
sqlite> .open C:/Work/db_sample.db sqlite> CREATE TABLE sample(id INTEGER UNIQUE,name TEXT,age INTEGER); sqlite> INSERT INTO sample VALUES(1,"TANAKA",25);
前回同様id列にはUNIQUE制約が設定されています。次に、以下のコードを実行してみましょう。
import sqlite3 # データベースに接続 dbname = r'C:\Work\db_sample.db' conn = sqlite3.connect(dbname) cur = conn.cursor() try: # トランザクションの開始 conn.execute('BEGIN') # データベースの操作 cur.execute('INSERT INTO sample VALUES(2,"YAMADA",30)') cur.execute('INSERT INTO sample VALUES(2,"OOTA",27)') except sqlite3.IntegrityError: conn.rollback() print('DataBaseError') except Exception as e: # 上記以外のエラー conn.rollback() print(f"Error: {e}") else: # 操作を確定 conn.commit() print('OK') finally: # SQLで読み込んで表示 for row in cur.execute('SELECT * FROM sample'): print(row) # データベース接続を閉じる cur.close() conn.close()
結果は以下のようになりました。
DataBaseError (1, 'TANAKA', 25)
先のコードでは2つのレコードを書き込んでいますが、UNIQUE制約を設けているid列が重複しているのでエラーとなります。結果、トランザクション処理が働いてデータの登録はされないというわけです。
データ登録の部分を以下のように書き換えて、エラーを解消してみましょう。
# データベースの操作 cur.execute('INSERT INTO sample VALUES(2,"YAMADA",30)') cur.execute('INSERT INTO sample VALUES(3,"OOTA",27)')
結果は以下のようになって、正常にレコードが登録されました。
OK (1, 'TANAKA', 25) (2, 'YAMADA', 30) (3, 'OOTA', 27)
その他のエラーが発生した場合
それではSQLiteではなくPython側でエラーが出た場合には、どうなるのでしょうか。データ登録の部分を以下のように書き換えてみましょう。
# データベースの操作 cur.execute('INSERT INTO sample VALUES(4,"MURAYAMA",22)') print(1 / 0)
登録するレコードのid列は重複していませんが、そのあとのprint関数では整数を0で割っていてるのでエラーとなってしまいます。結果は以下の様なりました。
Error: division by zero (1, 'TANAKA', 25) (2, 'YAMADA', 30) (3, 'OOTA', 27)
『0で割っています』と表示されています。これは、以下の部分が働いた結果です。
except Exception as e: # 上記以外のエラー conn.rollback() print(f"Error: {e}")
このように記述すると、エラーが発生した場合にエラー内容にかかわらず処理を中断してエラー内容を返します。この処理を他のエラー処理の前に記述すると、その他のエラー処理が無効になってしまうので気を付けましょう。全体の流れとしては以下のようになります。
try: メインの処理 except: メインの処理でエラーが発生した場合の処理 except Exception as e: 上記以外のエラーが発生した場合の処理 else: メインの処理が正常に実行された場合の処理 finally: メインの処理結果にかかわらず実行される処理
この流れでエラー処理はバッチリだと思います。
これでSQLiteの連載はいったん終了です
いかがでしょうか。SQLiteに関する連載はこれでいったん終了します。普段直接目にすることはないSQLiteデータベースですが、少しは理解が深まったと思います。また別なアプローチで学んでみたいと思います。お付き合いいただきありがとうございました!!