Flask SQLAlchemy と flask_sqlalchemy.SQLAlchemy クラスを使ってデバッグする方法
Flask SQLAlchemy でデバッグ用にクエリを表示する方法
logging モジュールを使う
Flask はデフォルトで logging
モジュールを備えており、SQLAlchemy クエリを含むすべてのアプリケーションログを出力できます。
1 設定ファイルの編集
以下のコードを app.config
または config.py
ファイルに追加します。
# SQLAlchemy クエリを DEBUG ログレベルで出力
SQLALCHEMY_ECHO = True
# ログレベルの設定
LOGGING = {
"version": 1,
"disable_existing_loggers": False,
"formatters": {
"verbose": {
"format": "[%(asctime)s] %(levelname)s %(module)s %(process)d %(thread)d %(message)s"
}
},
"handlers": {
"console": {
"level": "DEBUG",
"class": "logging.StreamHandler",
"formatter": "verbose",
}
},
"loggers": {
"sqlalchemy.engine": {
"level": "DEBUG",
"handlers": ["console"],
"propagate": False,
}
}
}
2 実行例
上記のコードを設定ファイルに追加後、アプリケーションを実行すると、コンソールに実行された SQL クエリが表示されます。
[2023-11-14 12:34:56] DEBUG sqlalchemy.engine.base.Engine SELECT users.id, users.name, users.email FROM users
[2023-11-14 12:34:56] DEBUG sqlalchemy.engine.base.Engine -- parameters: []
[2023-11-14 12:34:56] DEBUG sqlalchemy.engine.base.Engine (1, 'John Doe', '[email protected]')
flask_sqlalchemy.SQLAlchemy クラスを使う
flask_sqlalchemy
パッケージには、SQLAlchemy
クラスがあり、query_log
属性を使用して実行されたクエリを記録できます。
1 コード例
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
app = Flask(__name__)
app.config["SQLALCHEMY_DATABASE_URI"] = "sqlite:///database.db"
db = SQLAlchemy(app)
# クエリログを有効化
db.query_log = True
@app.route("/")
def index():
users = db.session.query(User).all()
return render_template("index.html", users=users)
if __name__ == "__main__":
app.run()
上記コードを実行すると、db.query_log
変数に実行されたクエリの一覧が格納されます。
[<sqlalchemy.orm.query.Query object at 0x10f54b490>, <sqlalchemy.orm.query.Query object at 0x10f54b550>]
各クエリオブジェクトには、statement
属性を使用して SQL クエリ文字列を取得できます。
for query in db.query_log:
print(query.statement)
SELECT users.id, users.name, users.email FROM users
sqlparse
モジュールを使って、SQL クエリをよりフォーマットされた状態で表示できます。
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from sqlparse import format
app = Flask(__name__)
app.config["SQLALCHEMY_DATABASE_URI"] = "sqlite:///database.db"
db = SQLAlchemy(app)
@app.route("/")
def index():
users = db.session.query(User).all()
return render_template("index.html", users=users)
if __name__ == "__main__":
app.run()
for query in db.query_log:
print(format(query.statement, reindent=True))
上記コードを実行すると、SQL クエリがインデント
logging モジュールを使う
from flask import Flask, render_template
from flask_sqlalchemy import SQLAlchemy
app = Flask(__name__)
app.config["SQLALCHEMY_DATABASE_URI"] = "sqlite:///database.db"
db = SQLAlchemy(app)
# SQLAlchemy クエリを DEBUG ログレベルで出力
SQLALCHEMY_ECHO = True
# ログレベルの設定
LOGGING = {
"version": 1,
"disable_existing_loggers": False,
"formatters": {
"verbose": {
"format": "[%(asctime)s] %(levelname)s %(module)s %(process)d %(thread)d %(message)s"
}
},
"handlers": {
"console": {
"level": "DEBUG",
"class": "logging.StreamHandler",
"formatter": "verbose",
}
},
"loggers": {
"sqlalchemy.engine": {
"level": "DEBUG",
"handlers": ["console"],
"propagate": False,
}
}
}
class User(db.Model):
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(80))
email = db.Column(db.String(120))
@app.route("/")
def index():
users = db.session.query(User).all()
return render_template("index.html", users=users)
if __name__ == "__main__":
app.run()
flask_sqlalchemy.SQLAlchemy クラスを使う
from flask import Flask, render_template
from flask_sqlalchemy import SQLAlchemy
app = Flask(__name__)
app.config["SQLALCHEMY_DATABASE_URI"] = "sqlite:///database.db"
db = SQLAlchemy(app)
# クエリログを有効化
db.query_log = True
class User(db.Model):
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(80))
email = db.Column(db.String(120))
@app.route("/")
def index():
users = db.session.query(User).all()
return render_template("index.html", users=users)
if __name__ == "__main__":
app.run()
sqlparse モジュールを使う
from flask import Flask, render_template
from flask_sqlalchemy import SQLAlchemy
from sqlparse import format
app = Flask(__name__)
app.config["SQLALCHEMY_DATABASE_URI"] = "sqlite:///database.db"
db = SQLAlchemy(app)
class User(db.Model):
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(80))
email = db.Column(db.String(120))
@app.route("/")
def index():
users = db.session.query(User).all()
return render_template("index.html", users=users)
if __name__ == "__main__":
app.run()
for query in db.query_log:
print(format(query.statement, reindent=True))
実行方法
flask run
ブラウザで http://localhost:5000/
を開き、以下の内容を確認できます。
- logging モジュールを使う
コンソールに実行された SQL クエリが表示されます。
- flask_sqlalchemy.SQLAlchemy クラスを使う
Flask SQLAlchemy でデバッグ用にクエリを表示するその他の方法
pdb
モジュールは、Python の標準ライブラリに含まれるデバッガーです。pdb
を使用して、実行中のコードをステップ実行し、変数の値を確認したり、SQL クエリを表示したりできます。
from flask import Flask, render_template
from flask_sqlalchemy import SQLAlchemy
import pdb
app = Flask(__name__)
app.config["SQLALCHEMY_DATABASE_URI"] = "sqlite:///database.db"
db = SQLAlchemy(app)
class User(db.Model):
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(80))
email = db.Column(db.String(120))
@app.route("/")
def index():
users = db.session.query(User).all()
# pdb を使ってクエリをデバッグ
pdb.set_trace()
return render_template("index.html", users=users)
if __name__ == "__main__":
app.run()
実行方法
上記コードを app.py
というファイル名で保存し、以下のコマンドを実行してアプリケーションを起動できます。
flask run
ブラウザで http://localhost:5000/
を開き、pdb
デバッガーが起動するのを待ちます。pdb
デバッガーが起動したら、以下のコマンドを使用してクエリを表示できます。
n
: 次のステップに進むp
: 変数の値を表示l
: ソースコードを表示q
: デバッガーを終了
SQLiteSpy などのツールを使う
SQLiteSpy
は、SQLite データベースを管理するための GUI ツールです。SQLiteSpy
を使用して、データベース内のデータを閲覧したり、編集したり、SQL クエリを実行したりできます。
使用方法
SQLiteSpy
をダウンロードしてインストールします。SQLiteSpy
を起動し、データベースファイルを開きます。- "Query" タブに移動し、SQL クエリを入力して実行します。
独自のロギングシステムを使う
上記の方法は汎用的なものですが、独自のロギングシステムを構築して、より詳細な情報を記録することもできます。
Flask SQLAlchemy でデバッグ用にクエリを表示するには、いくつかの方法があります。自分に合った方法を選択して、アプリケーションの開発を効率化しましょう。
sqlalchemy flask