SlideShare a Scribd company logo
Takayuki Shimizukawa
Django ORM道場
クエリの基本を押さえ
より良い形を身に付けよう
1
PyCon APAC 2023
● Philippines / Manila 在住
● Pythonプログラマー (2004~ 19年目
● Pythonコミュニティー運営
○ Python mini Hack-a-thon; 2009年~
○ Sphinx users JP; 2010年~
○ PyCon JP Association; accounting director
● (株) BePROUD; IT Architect
● Books 翻訳/執筆 (13冊)
about.me/shimizukawa
2
(CM)『Sphinxをはじめよう 第3版』
3
PythonドキュメンテーションといえばSphinx。
本書はSphinxで執筆し、re:VIew ビルダーで出力し、
組版までワンソースで出版まで行いました。
サイン会もやらせて
ていただきました
m(_ _)m
本日20F O'reillyさんでお安く購入できます!
アジェンダ
● このDjango ORM、どんなSQLを実行しているの?
● 一の形:実行しているSQLをいつも確認する
● 二の形:意図しないタイミングでのSQL発行を避ける
● 三の形:理想のSQLからORMを組む
● 質疑応答
4
デモコード
https://github.com/shimizukawa/pycon-apac-2023-django-orm-dojo
このDJango ORM、
どんなSQLを実行しているの?
5
6
それでは問題です
(実際の現場であったコードの簡易版です)
Q1. どんなSQLを実行してる?
7
レビュー時の
差分はここ
モデル定義
Q1. どんなSQLを実行してる?
8
モデル定義
Q1. どんなSQLを実行してる?
9
index.html
い. SELECT * FROM staff ORDER BY last_login
Q1. どんなSQLを実行してる?
10
い. SELECT * FROM staff ORDER BY last_login
ろ. SELECT pk, name FROM staff ORDER BY last_login
Q1. どんなSQLを実行してる?
11
Q1. どんなSQLを実行してる?
12
い. SELECT * FROM staff ORDER BY last_login
ろ. SELECT pk, name FROM staff ORDER BY last_login
は. 分からん
Q1. どんなSQLを実行してる?
13
い. SELECT * FROM staff ORDER BY last_login
ろ. SELECT pk, name FROM staff ORDER BY last_login
は. 分からん
Q1. どんなSQLを実行してる?
14
は. 分からん。実際に観察してみましょう。
DEMO
注目したのはここ
デモコード
https://github.com/shimizukawa/pycon-apac-2023-django-orm-dojo
Q1. どんなSQLを実行してる?
15
は. 分からん。実際に観察してみましょう。
SQLはQuerySetの使い方によって変わります。
注目したのはここ
「only?大丈夫かな?」と思ったあなたは、...
ORM師範になれるかも💪
「い」「ろ」を選んだあなたは、....
Django ORM道場へようこそ!
みなさんの選択は?
16
Django ORM道場へようこそ
● Django ORMは便利なやつですが、...
○ 時々、とても効率の悪いSQLを実行しているかも
○ 先ほどの例は、N+1と呼ばれるヤツです
● 経験や勘に頼らず、
処理を効率良く行うことができるよう、
道場で、基本の形から見なおしていきましょう。
17
3つの基本形
● 1つ、実行しているSQLをいつも確認しよう
● 1つ、意図しないタイミングでのSQL発行を避けよう
● 1つ、理想のSQLからORMを組もう
18
(CM) BeProud メンバー募集中!
19
Pythonプログラマー、他、ソフトウェア開発やっていくぞ!という
メンバーを通年募集中です!
今すぐBeProud ブースへ!!
自社サービス 書籍執筆 受託開発
一の形:実行しているSQLを
いつも確認しよう
20
実行しているSQLをいつも確認
21
DjangoでSQL実行ログを確
認するには、settings.py に
数行追加しましょう。
(日時もログ出力するにはもうちょ
っと色々設定してください)
では、コンソールログを確
認してみましょう。
ここを追加
実行しているSQLをいつも確認
22
1. 画面アクセスでSQLが表示される
2. migrationでもSQLが表示される
3. N+1の原因コードを修正
DEMO
デモコード
https://github.com/shimizukawa/pycon-apac-2023-django-orm-dojo
実行しているSQLをいつも確認
23
1. 画面アクセスでSQLが表示されました
2. migrationでもSQLが表示されました
3. N+1の原因コード修正が確認できました
補足: only も使い方次第
● DBとの通信を減らすには only が有効
○ 巨大なデータを持つカラムが参照不要と分かっている場合
○ 数万件を取得して、特定カラムだけ参照する場合
● QuerySetの使い方次第では逆効果に...
○ onlyに指定したカラムだけにアクセスする限り、問題なし
○ 指定外のカラムにアクセスすると、都度SQL発行が発動
24
ログは現状を映す鏡
● ログを見よう
○ スポーツ選手が鏡や動画で動きをチェックするように
○ ログ出力は、プログラミングにおける鏡
● SQLを常に観察する習慣を身に付けよう
○ QuerySetに手を加えるとき
○ QuerySetを使った処理を変更するとき
○ レビューに出すとき、SQL出力を添えると👍
○ レビューを受け取ったとき、SQLも確認すると👍
25
ログ以外でSQL確認
26
1. django-debug-toolbar
○ 👍Web画面にデバッグツールバーが
追加され、そこでSQL情報を確認
○ 👎Web画面がないと使えない
■ 最近はDjangoで画面を表示せずAPIサーバーのみの場合も増えており...
2. django-silk
○ 👍SQL実行を専用画面で俯瞰して確認
○ 👎DB保存するので本番利用は避けて!
[CM] 『自走プログラマー』
『自走プログラマー』は120のベストプラクティス
をPythonの先輩から学び、プログラミング中級者を
目指すための書籍です。
Django ORMの話題を含む、コードレビューや技術指導など
で伝えたい事例を多数紹介しています。
Web抜粋版の引用やリンクはご自由にどうぞ!
今すぐ 自走プログラマー で検索!
27
二の形:意図しないタイミング
でのSQL発行を避けよう
28
29
それでは問題 Q2 です
(実際の現場であった事例を元にした創作です)
Q2. 意図しないSQL発行を防止するには?
30
qs = SomeModel.objects.filter(...) の後どうする?
Q2. 意図しないSQL発行を防止するには?
31
qs = SomeModel.objects.filter(...) の後どうする?
QuerySetをテンプレートに渡したらN+1
が発生したのが問題でした
Q2. 意図しないSQL発行を防止するには?
32
qs = SomeModel.objects.filter(...) の後どうする?
QuerySetをテンプレートに渡したらN+1
が発生したのが問題でした
それなら、QuerySetをテンプレートに渡
さなければ問題にならないのでは?
Q2. 意図しないSQL発行を防止するには?
33
qs = SomeModel.objects.filter(...) の後どうする?
い. list(qs)でSQL発行を確定し、データクラスに詰め替え
それなら、QuerySetをテンプレートに渡
さなければ問題にならないのでは?
Q2. 意図しないSQL発行を防止するには?
34
qs = SomeModel.objects.filter(...) の後どうする?
い. list(qs)でSQL発行を確定し、データクラスに詰め替え
ろ. list(qs.values(...))でSQL発行を確定し、辞書化
それなら、QuerySetをテンプレートに渡
さなければ問題にならないのでは?
Q2. 意図しないSQL発行を防止するには?
35
qs = SomeModel.objects.filter(...) の後どうする?
い. list(qs)でSQL発行を確定し、データクラスに詰め替え
ろ. list(qs.values(...))でSQL発行を確定し、辞書化
は. qsをやめてpandas.read_sql()してDataFrame上で処理
それなら、QuerySetをテンプレートに渡
さなければ問題にならないのでは?
Q2. 意図しないSQL発行を防止するには?
36
qs = SomeModel.objects.filter(...) の後どうする?
い. list(qs)でSQL発行を確定し、データクラスに詰め替え
ろ. list(qs.values(...))でSQL発行を確定し、辞書化
は. qsをやめてpandas.read_sql()してDataFrame上で処理
に. 場合による
Q2. 意図しないSQL発行を防止するには?
37
qs = SomeModel.objects.filter(...) の後どうする?
い. list(qs)でSQL発行を確定し、データクラスに詰め替え
ろ. list(qs.values(...))でSQL発行を確定し、辞書化
は. qsをやめてpandas.read_sql()してDataFrame上で処理
に. 場合による
Q2. 意図しないSQL発行を防止するには?
38
に. 場合による。QuerySetの便利さを捨てる場合、デメリットも。
● い. list(qs)でSQL発行を確定し、データクラスに詰め替え
○ 👍クラス定義によってデータの目的が明確になり、扱いやすい
○ 👎詰め替えの実装はけっこう手間がかかる
■ 期待通り詰め替えられているかのUTも書かないといけないよね?
● ろ. list(qs.values(...))でSQL発行を確定し、辞書化
○ 👍取り出した時点で辞書になっているので、データ詰め替えが不要
○ 👎QuerySetを活用するDRF Serializer等とは相性が悪い
● は. qsをやめてpandas.read_sql()してDataFrame上で処理
○ 👍SQL発行が確定するのは間違いなさそう
○ 👎Pandasを持ち出す必要があったのかはよく考えよう
[事例]データクラスに詰め替え
あるプロジェクトでは、
● データクラスに詰め替える実装に変更
○ データ取得、加工、詰め替え、利用でレイヤー増加
■ 実装コード、テストコードの増加(開発時間の増加)
■ コードの見通しが悪化(レイヤーが増えただけ)
■ 付け焼刃の対策が増加(レイヤー間の変数引き回し)
■ データクラスが目的のないバケツ化(dictと変わらない)
● この状態で、ORMクエリの変更をレビューしました(´・ω・`)
39
40
ムダに複雑なコードは問題です
どのような対策が考えられるでしょう?
複雑な問題は複雑なまま解かない
● 課題: コードが複雑で変更が適切か分からない
○ 対策: コードをシンプルにしてから考える
● 課題: 複数レイヤーに分散して見通しが悪い
○ 対策: 考えるために、一旦コードを1ファイルへ集約
● 課題: データ詰め替えが手間
○ 対策: 省略できる処理をばっさり削除(開発ルールやフレームワークの都合は一旦無視)
● 課題: データクラスがバケツ化
○ 対策: データクラス廃止を検討
● 課題: 付け焼き刃の対策コードが多い
○ 対策: シンプルなコードで対策を考える
41
Q1のコードを例に説明
views.py
index.html
42
try1.py
Q1のコードを1ファイルに集約
43
1ファイルに集約して試行錯誤
44
DEMO
1.try1.py にコードを集約
2.python try1.py
3. ログを確認しながら試行錯誤
デモコード
https://github.com/shimizukawa/pycon-apac-2023-django-orm-dojo
ここを変更
try1.py
1ファイル上で試行錯誤した結果
45
試行錯誤のループ
● while 欲しいORMクエリが書けたか:
○ コード上に分散したORMクエリを修正
○ QuerySetの利用箇所を修正
○ その処理を呼び出すWeb画面を操作
○ DjDTやSlikを確認するため、画面を操作
コードが分散しているし、画面操作が多くて面倒....
1ファイルに集約して、コマンド実行でサクサク確認しよう
46
datamodels.py
views.py
serializers.py
index.html
試行錯誤の高速化
● while 欲しいORMクエリが書けたか:
○ 1つの .py ファイルを修正
○ .py ファイルを実行して、ログを確認
1ファイルに集約するメリット
● コードが1箇所で把握しやすい
● 画面操作が不要
● 適切なモジュールへの配置や整形に気にせず書ける
47
try1.py
try1.py
意図しないSQL発行を防止するには
48
1. コードの全体像を把握して、
2. ORMクエリの準備、データ加工、利用の処理から、
3. 必要十分なSQLが発行されるように全体を調整し、
4. 最も効率の良いコードにまとめる
この作業を、シンプルなコードで高速に回しましょう
models.py
datamodels.py
serializers.py
views.py
index.html
try1.py
models.py serializers.py
views.py index.html
三の形:理想のSQLから
ORMを組もう
49
三の形:理想のSQLから
ORMを組もう
50
続きは 書籍で!
ありがとうございました
Questions?
51
https://about.me/shimizukawa
Welcome to
Sprint after-party of
Register now!! →
Let’s have fun
at the end of
2023-10-29T18:30:00+09:00
Venue: Shibuya
Fee: >6,000 JPY
(discount for students)
(CM) 10/29(Sun) 18:30~ 非公式Party

More Related Content

PDF
どうする計画駆動型スクラム(スクラムフェス大阪2023 発表資料)
PDF
今からでも遅くないDBマイグレーション - Flyway と SchemaSpy の紹介 -
PDF
MagicOnion~C#でゲームサーバを開発しよう~
PPTX
Azure Search 大全
PDF
レガシーコードとの付き合い方とテストでの話
PDF
大企業アジャイルの勘所 #devlovex #devlovexd
PPTX
Bapp Storeを調べてみたよ!
PDF
Redmineの情報を自分好みに見える化した話
どうする計画駆動型スクラム(スクラムフェス大阪2023 発表資料)
今からでも遅くないDBマイグレーション - Flyway と SchemaSpy の紹介 -
MagicOnion~C#でゲームサーバを開発しよう~
Azure Search 大全
レガシーコードとの付き合い方とテストでの話
大企業アジャイルの勘所 #devlovex #devlovexd
Bapp Storeを調べてみたよ!
Redmineの情報を自分好みに見える化した話

What's hot (20)

PPTX
最新の多様な深層強化学習モデルとその応用(第40回強化学習アーキテクチャ講演資料)
PDF
Python 3.9からの新定番zoneinfoを使いこなそう
PDF
モノタロウの開発・リリースサイクルを支えるJenkinsの活用事例 - Jenkins Day Japan 2021
PPTX
Dockerからcontainerdへの移行
PPTX
Imprementation of realtime_networkgame
PDF
ウォーターフォールとアジャイルを考える #ita_ws
PDF
Springを何となく使ってる人が抑えるべきポイント
PDF
PostgreSQLアンチパターン
PDF
インフラエンジニアの綺麗で優しい手順書の書き方
PDF
「Redmineの運用パターン集~私に聞くな、チケットシステムに聞け」
PDF
パターン QA to AQ: 伝統的品質保証(Quality Assurance)からアジャイル品質(Agile Quality)へ
PDF
いつやるの?Git入門
PDF
思考停止しないアーキテクチャ設計 ➖ JJUG CCC 2018 Fall
PPTX
Kafkaを活用するためのストリーム処理の基本
PPTX
3 Amigosの考え方で、独立したQAチームがアジャイルテストチームになるまでの話
PDF
[db tech showcase Tokyo 2017] E21: InfluxDB+αで時系列データの異常検知を可視化してみた by 株式会社インサイ...
PPTX
PostgreSQL開発コミュニティに参加しよう!(PostgreSQL Conference Japan 2021 発表資料)
PDF
アジャイル・スクラム時代のパタン・ランゲージとアレグザンダー理論
PDF
JaSST Tokyo 2022 アジャイルソフトウェア開発への統計的品質管理の応用
最新の多様な深層強化学習モデルとその応用(第40回強化学習アーキテクチャ講演資料)
Python 3.9からの新定番zoneinfoを使いこなそう
モノタロウの開発・リリースサイクルを支えるJenkinsの活用事例 - Jenkins Day Japan 2021
Dockerからcontainerdへの移行
Imprementation of realtime_networkgame
ウォーターフォールとアジャイルを考える #ita_ws
Springを何となく使ってる人が抑えるべきポイント
PostgreSQLアンチパターン
インフラエンジニアの綺麗で優しい手順書の書き方
「Redmineの運用パターン集~私に聞くな、チケットシステムに聞け」
パターン QA to AQ: 伝統的品質保証(Quality Assurance)からアジャイル品質(Agile Quality)へ
いつやるの?Git入門
思考停止しないアーキテクチャ設計 ➖ JJUG CCC 2018 Fall
Kafkaを活用するためのストリーム処理の基本
3 Amigosの考え方で、独立したQAチームがアジャイルテストチームになるまでの話
[db tech showcase Tokyo 2017] E21: InfluxDB+αで時系列データの異常検知を可視化してみた by 株式会社インサイ...
PostgreSQL開発コミュニティに参加しよう!(PostgreSQL Conference Japan 2021 発表資料)
アジャイル・スクラム時代のパタン・ランゲージとアレグザンダー理論
JaSST Tokyo 2022 アジャイルソフトウェア開発への統計的品質管理の応用
Ad

Similar to Django ORM道場:クエリの基本を押さえ,より良い形を身に付けよう (20)

PDF
Nodeにしましょう
PDF
ユーザ・デザイナーから見たPlone CMSのアピールポイント
PDF
Django で始める PyCharm 入門
PPTX
210630 python
KEY
Windowsにpythonをインストールしてみよう
PDF
2014年を振り返る 今年の技術トレンドとDockerについて
PDF
オンプレエンジニアがクラウドエンジニアを夢見て。じっと手を見る。
PDF
いままでのJaSSTnanoLT動画を振り返る&おススメしたいの! / Looking back and recommend on the JaSSTna...
PDF
Logcatの話
PDF
Pythonで検索エンジン2
PDF
20120915 Pythonは本当にBlenderの役に立っているか?
PDF
20101127 Android Usability Seminar
KEY
初心者向けAndroidゲーム開発ノウハウ
PDF
Platform io で シュッと arduino 開発を高速化しよう speed up your arduino development with p...
PPTX
APIドキュメントの話 #sphinxjp
KEY
SnapDishの事例
PDF
アジャイルソフトウェア開発の道具箱
PDF
Boost.勉強会 #13 @仙台 鳥小屋
PDF
Python & PyConJP 2014 Report
KEY
エンジニアの為のWordPress入門 〜WordPressはWebAppプラットフォームです〜
Nodeにしましょう
ユーザ・デザイナーから見たPlone CMSのアピールポイント
Django で始める PyCharm 入門
210630 python
Windowsにpythonをインストールしてみよう
2014年を振り返る 今年の技術トレンドとDockerについて
オンプレエンジニアがクラウドエンジニアを夢見て。じっと手を見る。
いままでのJaSSTnanoLT動画を振り返る&おススメしたいの! / Looking back and recommend on the JaSSTna...
Logcatの話
Pythonで検索エンジン2
20120915 Pythonは本当にBlenderの役に立っているか?
20101127 Android Usability Seminar
初心者向けAndroidゲーム開発ノウハウ
Platform io で シュッと arduino 開発を高速化しよう speed up your arduino development with p...
APIドキュメントの話 #sphinxjp
SnapDishの事例
アジャイルソフトウェア開発の道具箱
Boost.勉強会 #13 @仙台 鳥小屋
Python & PyConJP 2014 Report
エンジニアの為のWordPress入門 〜WordPressはWebAppプラットフォームです〜
Ad

More from Takayuki Shimizukawa (20)

PPTX
Navigating Python: Milestones from Essential Reads
PPTX
IKEv2-VPN PyHackCon2023
PDF
OpenTelemetryでWebシステムの処理を追跡しよう - DjangoCongress JP 2022
PDF
プログラマーとの出会い - Hello, Programmer! at PyCon Kyushu 2022
PDF
Webアプリを並行開発する際のマイグレーション戦略
PDF
『自走プログラマー』 が我々に必要だった理由
PDF
エキスパートPythonプログラミング改訂3版の読みどころ
PPTX
RLSを用いたマルチテナント実装 for Django
PPTX
独学プログラマーのその後
PPTX
【修正版】Django + SQLAlchemy: シンプルWay
PDF
Sphinx customization for OGP support at SphinxCon JP 2018
PDF
Pythonはどうやってlen関数で長さを手にいれているの?
PPTX
仕事で使うちょっとしたコードをOSSとして開発メンテしていく - Django Redshift Backend の開発 - PyCon JP 2016
PPTX
Easy contributable internationalization process with Sphinx @ PyCon APAC 2016
POTX
素振りのススメ at Python入門者の集い
PPTX
世界のSphinx事情 @ SphinxCon JP 2015
PPTX
JUS関西 Sphinxワークショップ@関西 Sphinx紹介
PPTX
Sphinxで作る貢献しやすい ドキュメント翻訳の仕組み
PPTX
Sphinx autodoc - automated api documentation - PyCon.KR 2015
PPTX
Easy contributable internationalization process with Sphinx @ pyconmy2015
Navigating Python: Milestones from Essential Reads
IKEv2-VPN PyHackCon2023
OpenTelemetryでWebシステムの処理を追跡しよう - DjangoCongress JP 2022
プログラマーとの出会い - Hello, Programmer! at PyCon Kyushu 2022
Webアプリを並行開発する際のマイグレーション戦略
『自走プログラマー』 が我々に必要だった理由
エキスパートPythonプログラミング改訂3版の読みどころ
RLSを用いたマルチテナント実装 for Django
独学プログラマーのその後
【修正版】Django + SQLAlchemy: シンプルWay
Sphinx customization for OGP support at SphinxCon JP 2018
Pythonはどうやってlen関数で長さを手にいれているの?
仕事で使うちょっとしたコードをOSSとして開発メンテしていく - Django Redshift Backend の開発 - PyCon JP 2016
Easy contributable internationalization process with Sphinx @ PyCon APAC 2016
素振りのススメ at Python入門者の集い
世界のSphinx事情 @ SphinxCon JP 2015
JUS関西 Sphinxワークショップ@関西 Sphinx紹介
Sphinxで作る貢献しやすい ドキュメント翻訳の仕組み
Sphinx autodoc - automated api documentation - PyCon.KR 2015
Easy contributable internationalization process with Sphinx @ pyconmy2015

Django ORM道場:クエリの基本を押さえ,より良い形を身に付けよう

Editor's Notes

  • #3: I have been using Python since 2004 My main activities are as follows: Organizing Python communities in Japan: "Python mini Hack-a-thon", "Sphinx users JP" and "PyCon JP Association" non-profit organization. Working as an IT architect at BePROUD Inc in Japan. I also translate and write Python related books. For more information, please visit https://about.me/shimizukawa
  • #7: ある日レビュー依頼がきました。 差分は問題なさそうですが、ふと、差分とは関係ない別のことが気になりました。
  • #8: 差分のひとつにクエリのorder_by条件の変更があり、それ自体は問題無さそうです。 ここで私が気になったのは、このクエリがどういうSQLを実行しているか、です。 このクエリ、どんなSQLを実行していると思いますか?
  • #9: ちなみに、モデル定義はこんな感じ
  • #10: ちなみに、テンプレートはこんな感じです。
  • #15: 注目したのは、onlyの部分です。
  • #27: DB保存すると、トランザクションが競合してロールバックしちゃったり、DB容量を圧迫したり、パフォーマンスに影響を与えたりします。
  • #28: 弊社ビープラウドブースにて、見本を読めますので、ブースにもお立ち寄りください~
  • #40: 先ほどの例ではORMクエリをテンプレートに渡したことで、N+1が発生したので、代わりにデータクラスに詰め替える実装にしました。しかし今度はソースコードが複雑になって開発しづらくなってしまいました。 ビューの処理内にSQL発行を閉じ込めることで意図しないタイミングでのSQL発行を避ける方針は良いですが、実装の手間が増えてしまうのも考え物です。
  • #47: Djangoテンプレートのforループ処理やフィルター処理などに利用箇所が分散していることがあります。 また、クラスベースビューではベースとなるquerysetの用意とそこにクエリ条件を追加する処理が分かれていたり、Django REST Frameworkではさらにシリアライザの都合に合わせてselect_relatedやprefetch_relatedの用意が必要になったりします。
  • #55: Expert Python Programming, Fourth Edition's Target Audience are: Python developers who want to master Python in depth Python developers who use Python in their work Overview: This book covers the tools, techniques, and best practices that advanced Python programmers use in their work. Readers will learn advanced Python concepts and skills to create more efficient and high-quality Python code.
  • #56: Translation and writing works Since the first book in 2010, I have continued to translate and write as a side job while working on Python web applications. This year, my 13th book was published. Today I would like to share with you four books that mark milestones in my experience as a author and a translator. They are entitled, "Python books as milestones"