質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
SQLite

SQLiteはリレーショナルデータベース管理システムの1つで、サーバーではなくライブラリとして使用されている。

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

デバッグ

デバッグはプログラムのバグや欠陥を検知し、開発中のバグを取り除く為のプロセスを指します。

Q&A

解決済

2回答

581閲覧

Sqlite3のtransactionをcommitする前に内容を確認したい

namuyan

総合スコア76

SQLite

SQLiteはリレーショナルデータベース管理システムの1つで、サーバーではなくライブラリとして使用されている。

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

デバッグ

デバッグはプログラムのバグや欠陥を検知し、開発中のバグを取り除く為のプロセスを指します。

0グッド

1クリップ

投稿2018/03/08 16:42

Python3.5でsqlite3を使用しています。
あるトランザクションを反映させる前に変更内容を確認したいと思います。
通常ならばコードを見れば何をしているかわかるのですが、
前提として実行したSQLは全く分からない状況にあります。
実行したSQLの一覧でも取得できればいいのですが、何か良い方法はありませんか?
解答の方を宜しくお願いします。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

umyu

2018/03/08 22:44 編集

どういう要件があって「トランザクションを反映させる前に変更内容を確認したい」のでしょうか?
namuyan

2018/03/09 06:04

外部からひとまとまりのコードが流れてきて内部の状態変化に寄与します。このコードの内容はわからずそのままcommitするのは躊躇されるので確認作業を入れようと考えました。
guest

回答2

0

ベストアンサー

sqlite3.Connection#set_trace_callback関数が使えます。

以下はサンプルコードです。

Python

1# -*- coding: utf-8 -*- 2import sqlite3 3from contextlib import closing 4from logging import FileHandler, DEBUG, getLogger 5 6handler = FileHandler("test.log") 7handler.setLevel(DEBUG) 8logger = getLogger("test") 9logger.setLevel(DEBUG) 10logger.addHandler(handler) 11 12 13def main() -> None: 14 db_name = ':memory:' 15 # connectionの閉じ忘れを防ぐためにcontextlib#closingを使用。 16 with closing(sqlite3.connect(db_name)) as conn: 17 conn.set_trace_callback(print) 18 # ログ・ファイルにSQLを書き出したい時は以下のコメントを外してくださいな。 19 #conn.set_trace_callback(logger.debug) 20 conn.execute('SELECT 1') 21 22 23if __name__ == "__main__": 24 main()

投稿2018/03/09 06:18

編集2018/03/09 06:29
umyu

総合スコア5846

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

追記:スミマセン、ラッパーのアイデアが浮かんだのでコメントしてしまいましたが、1,2などによい方法があるかどうか調べずに回答しています。「そんな方法も考えられる」ぐらいに受け取っていただければと思います。


  1. sqlite3のデバッグ用機能がないか調べてみる
  2. デバッグ用のフレームワーク的なものがないか調べてみる(アマチュアなので積極的に調べません)
  3. デバッグ用ラッパーを作ってみる(アマチュアなのでこういうの書きたくなります)

自分だと繰り返し使いそうなら適当にデバッグ用ラッパーを書こうとしてしまうかも知れません。

アプリソース

Python

1#import sqlite3 2import sqlite3_dbg as sqlite3 # for debugging 3...

sqlite3_dbg.py(デバッグ用ラッパー)

python

1import sqlite3 2 3def connect(*args): 4 return ConnectionWrapper(sqlite3.connect(*args)) 5 6class ConnectionWrapper(sqlite3.Connection): 7 def __init__(self, delegate): 8 self.delegate = delegate 9 self.sqls = [] 10 11 def cursor(self): 12 return CursorWrapper(self, delegate.cursor()) 13 14 def dbg_execute(args): 15 self.sqls.append(args) 16 17 def commit() 18 # self.sqlsを参照して何かする 19 self.delegate.commit() 20 self.sqls = [] 21 22 ... 23 24class CursorWrapper(sqlite3.Cursor): 25 def __init__(self, connection_wrapper, delegate): 26 self.connection_wrapper = connection_wrapper 27 self.delegate = delegate 28 29 def execute(self, *args): 30 self.delegate.execute(*args) 31 self.connection_wrapper.dbg_execute(args) 32 33 ...

できたらデバッグ用に一部の関数だけパッチしたい気もしますが

python

1def patch_sqlite3(): 2 org_connect = sqlite3.connect 3 sqlite3.connect = dbg_connect 4 def dbg_connect(*args): 5 ...

こうしたライブラリーのattributeは普通readonlyなのでこういうパッチという安直な手は打てないかと思います。

そういうわけでラッパーをイメージするのですが、ラッパーにすると少なくとも自分が使う機能についてオーバーライドしないといけないのであまり複雑な機能のものは作ること自体が面倒です。しかしsqlite3ぐらいであればそれほど面倒でもない感じがしました。

ソースを変更するのではなくPYTHONPATHに細工をした方が都合がいいこともあるかも知れません。しかし、あくまでデバッグ目的なのでimportが1ファイルだけならあまり凝らずにimportを書き換えた方がよいのかも知れません。

投稿2018/03/08 22:15

編集2018/03/08 22:22
KSwordOfHaste

総合スコア18394

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

KSwordOfHaste

2018/03/09 05:06 編集

コメントありがとうございます。 なるほどやはり1の機能があるんですね!そんな気がしましたw; --- 自分は回答ひかえますので、お手すきなら回答つけていただければと思います。>umyuさん
KSwordOfHaste

2018/03/09 00:18

to: 質問者さん 自分も調べずに直感的に「こうしたらいいかな」みたいに考えちゃいましたが、やはりリファレンスをよく見るというのが教訓ではないでしょうか。お互い気を付けましょう!(自爆)
umyu

2018/03/09 00:36

回答にクレームを付けた形になって申し訳ないです。。。 私としては質問内容に追記依頼しましたが、どういう要件なのかで回答が変わると思ってるので。。。
KSwordOfHaste

2018/03/09 00:49

いえいえ、解答直後に「自分でもあまり考えずにコメントした」と思ったので追記したぐらいですし。 なお、自分は「期待通りの結果が得られないときコードを追っかけて調べるのが大変なので、要領よくどんなSQLを(commit間で)出しているかデバッグしたい」のかなぁという想定でコメントしちゃってます。
namuyan

2018/03/09 06:06

こんにちは、umyuさん。 解答をして頂ければBAにしますのでお願いします。
umyu

2018/03/09 06:15

namuyanさんへ了解です。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問