この記事は(第157回)Python mini Hack-a-thon(ハイブリッド) の記事です。
先週、こちらの記事を投稿したところ、先輩からアドバイスをもらいました。
どんなSQLが実行されているか出力しながら検証すると理解が深まるかなと思いました。
— かしゅー (@kashew_nuts) 2024年3月2日
確かにSQLを出力せずに調べていた(その前段階で「?」だった)事もあったので、今回は出力してみることにします。
SQLの出力方法
いつもながら自走プログラマーの内容を参考に、settings.pyに記述します。設定内容はリンク先に記述されているので割愛します。
60:Django ORMでどんなSQLが発行されているか気にしよう
動かしてみる
まずはUserを取得してみます。
まず、結果は通常のauth.User
を利用しているので予想通り、auth_user
を普通に取得した、と言う内容でした。
>>> nibu = User.objects.get(username="nibu") (0.001) SELECT "auth_user"."id", "auth_user"."password", "auth_user"."last_login", "auth_user"."is_superuser", "auth_user"."username", "auth_user"."first_name", "auth_user"."last_name", "auth_user"."email", "auth_user"."is_staff", "auth_user"."is_active", "auth_user"."date_joined" FROM "auth_user" WHERE "auth_user"."username" = 'nibu' LIMIT 21; args=('nibu',); alias=default
次に、more
についても調べてみます。
こちらも予想通りでした。
※前回の記事の動画のコードを元にしたので、drivers_more
になっています。
>>> nibu_more = More.objects.get(user=nibu) (0.000) SELECT "drivers_more"."id", "drivers_more"."user_id", "drivers_more"."address", "drivers_more"."postal_code" FROM "drivers_more" WHERE "drivers_more"."user_id" = 1 LIMIT 21; args=(1,); alias=default
この次、nibu.more
だと自分の想定とはちょっと異なりました。
JOINではなく、drivers_more
を呼び出した状態になっています。
自分のイメージは結合しているのかな?と思っていましたが、SQL的には結合せず効率の良いものが発行されていたことがわかります。
>>> nibu.more (0.000) SELECT "drivers_more"."id", "drivers_more"."user_id", "drivers_more"."address", "drivers_more"."postal_code" FROM "drivers_more" WHERE "drivers_more"."user_id" = 1 LIMIT 21; args=(1,); alias=default <More: More object (1)>
となると、nibu_more
からuser
を参照した場合も同様かな?と思ったところ、同様でした。
>>> nibu_more.user (0.002) SELECT "auth_user"."id", "auth_user"."password", "auth_user"."last_login", "auth_user"."is_superuser", "auth_user"."username", "auth_user"."first_name", "auth_user"."last_name", "auth_user"."email", "auth_user"."is_staff", "auth_user"."is_active", "auth_user"."date_joined" FROM "auth_user" WHERE "auth_user"."id" = 1 LIMIT 21; args=(1,); alias=default <User: nibu>
というわけで、どんなSQLが発行されているかを確認するのは大事だなと再認識しました。
もうちょっと複雑だったり、初めてみるQuerySet APIを利用したものはSQLを確認しようとしていましたが、こういう所から1つずつ意識していこうと思います。