Flask SQLAlchemy と flask_sqlalchemy.SQLAlchemy クラスを使ってデバッグする方法

2024-04-02

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 クエリを実行したりできます。

使用方法

  1. SQLiteSpy をダウンロードしてインストールします。
  2. SQLiteSpy を起動し、データベースファイルを開きます。
  3. "Query" タブに移動し、SQL クエリを入力して実行します。

独自のロギングシステムを使う

上記の方法は汎用的なものですが、独自のロギングシステムを構築して、より詳細な情報を記録することもできます。

Flask SQLAlchemy でデバッグ用にクエリを表示するには、いくつかの方法があります。自分に合った方法を選択して、アプリケーションの開発を効率化しましょう。


sqlalchemy flask


SQLAlchemy で複雑な Many-to-Many 関係をシンプルに扱う: 仮想列の威力

SQLAlchemy では、Many-to-Many 関係を定義する際に、関連属性を独自の仮想列にマッピングすることで、より柔軟なデータ操作やクエリが可能になります。この方法は、特に複雑な関係構造を持つ場合や、関係に固有の属性を管理する必要がある場合に役立ちます。...


SQLAlchemyで関連エンティティを効率的にロード:JoinedLoadとLoadOnly

SQLAlchemyは、Pythonでオブジェクトリレーショナルマッピング(ORM)を行うためのライブラリです。JoinedLoadとLoadOnlyは、関連するエンティティを効率的にロードするための機能です。JoinedLoadは、関連するエンティティを一度のクエリでロードする機能です。これにより、複数のクエリを実行する必要がなくなり、パフォーマンスが向上します。...


SQL SQL SQL SQL Amazon で見る



SQLAlchemyにおけるSQL文と返却行のロギング:わかりやすく解説

まず、ロギングを行うためのライブラリをインストールする必要があります。一般的には、loggingライブラリを使用します。ロガーを設定するには、以下の手順を実行します。ロガーインスタンスを作成します。ロガーのレベルを設定します。ロガーにハンドラーを追加します。