Make組ブログ

Python、Webサービスや製品開発、ライブラリー開発についてhirokikyが書きます

DjangoのORMが実行してるSQLの見方 (とdjango-debug-toolbar のススメ)

DjangoのORMが実行してるSQLの見方 (とdjango-debug-toolbar のススメ)

djangoddebugttoolbar 使おう。

以下の様な記事があった。

django.db.connection.queries を使うとよいそうです。でもこれを覚えるのはちょっと大変。

ここで djangoddebugttoolbar 使えばもっと楽にできるのでオススメしたい。 どうするのかというと、 djangoddebugttoolbar の debugsqlshell という機能を使う。 これは普段の manage.py shell とほとんど同じなんだけど、SQLが実行されたときは、そのSQLを表示してくれるというもの。

(djangoddebugttoolbar は画面上にデバッグ用のパネルを表示してくれたりする、頼もしいやつ)

djangoddebugttoolbar をインストールすると管理コマンドで debugsqlshell というのが 使えるようになるので、設定とかもそれほど必要ない。

インストール:

$ easy_install django-debug-toolbar

設置ファイルに記述:

# settings.py
INSTALLED_APPS += ('debug_toolbar',)

ってすれば、もう使える。 djangoddebugttoolbar の機能をモリモリ使うなら他にも設定は要るけど、 debugsqlshell だけなら、まぁこれでもOK。

# $ ./manage.py debugsqlshell

>>> from django.contrib.auth.models import User
>>> User.objects.all()
SELECT "auth_user"."id",
       "auth_user"."username",
       "auth_user"."first_name",
       "auth_user"."last_name",
       "auth_user"."email",
       "auth_user"."password",
       "auth_user"."is_staff",
       "auth_user"."is_active",
       "auth_user"."is_superuser",
       "auth_user"."last_login",
       "auth_user"."date_joined"
FROM "auth_user" LIMIT 21  [0.40ms]

[<User: hirokiky>]
>>> qs = User.objects.all()[:10]
>>> qs
SELECT "auth_user"."id",
       "auth_user"."username",
       "auth_user"."first_name",
       "auth_user"."last_name",
       "auth_user"."email",
       "auth_user"."password",
       "auth_user"."is_staff",
       "auth_user"."is_active",
       "auth_user"."is_superuser",
       "auth_user"."last_login",
       "auth_user"."date_joined"
FROM "auth_user" LIMIT 10  [0.35ms]

[<User: hirokiky>]
>>> 

こんなかんじ。 クエリセットが評価されてSQLが投げなれるタイミングもよくわかる。

でも djangoddebugttoolbar の本領はこんなもんじゃなくて、画面上にデバッグ用のパネルを表示してなんぼのもの。 使うデバッグ用のパネルは設定で選べるんだけど、とくに良いのが debug_toolbar.panels.sql.SQLDebugPanel 。 これを追加してあげれば、1リクエスト中に走ったSQLと、その実行時間をガントチャートで表示してくれる。 やたら遅い画面とかあるときに原因 (クエリ1000件以上投げてるじゃん!とか) をすぐ発見できるのでオススメ。

djangoddebugttoolbar がいないと生きていけない。