Make組ブログ

Python、Webアプリや製品・サービス開発についてhirokikyが書きます。

PyCon JP 2024はディープなトークが多くて良かった #pyconjp2024

2024年9月27日、28日はPyCon JP 2024のカンファレンスデーでした。

https://2024.pycon.jp/

今回はトークの満足度が個人的にとても高かった。とくにコア開発、処理系、PEP Author(仕様策定に携わる人)のトークも充実しており、トークだけを見てもイベントとして贅沢なものだったと思います。

参加したトークはこのあたりでした:

  • キーノート(1日目)
  • Django Ninjaで高速なAPI開発を実現する: 実践ガイドとベストプラクティス
  • Crimes with the Python syntax
  • Extracting Structured Data from LLMs with LangChain and Pydantic
  • An overview of the optimisation pipeline in CPython 3.13 and onwards
  • Unlocking the Parallel Universe: Subinterpreters and Free-Threading in Python 3.13
  • 【招待講演】PythonUTF-8
  • Unlocking Python's Core Magic
  • CloudFlare Workers in Pythonでサーバーレスアプリケーションを作ろう
  • Sleuthing in Cython: Wrapping and Debugging Legacy C Libraries for Python
  • Playing games in the browser with WASM
  • The Wheelhouse of Horrors
  • Why Knowing Cython Helps in Understanding Python: A Deep Dive into Cython & PVM
  • プロダクションでのPython非同期ユースケース - Trio/Trio-Utilを中心に
  • キーノート(2日目)

すべては紹介しきれないので、印象に残った点だけここで挙げさせてください。

ディープなトークの数々

Python 3.13で入るCPythonの最適化の話、Wheelパッケージの構造と動作の話(どのようにしてsoファイルを同梱するのか)、言語としてUTF-8を標準にしていく過程と開発者内での議論の話が印象的でした。コア開発に関わる人たちによる直接の話であり、Pythonそのものについて「どうより良くしていくか」、「どうなっているのか」という内部的な話を聞けたのが貴重でした。

Python 3.13ではスタックマシンの最適化のため、ある動作が繰り返された場合にTier2というマシンでTier1内の処理を反復しないような制御について説明されており興味深かったです。

PythonエンコーディングUTF-8にしていく過程の話も、いかにコア開発者の中でコンセンサスを取り、後方互換性を担保しながら一つひとつ前に進めていくリアルな話が大変面白かったです。完璧な正解のない世界ですし、僕たちが知らないような動作を保証する必要があったりと難しいものだと感じました。それを進めてくれるmethaneさんに改めて感謝したいものです。ありがとうございます。

初日のキーノート:James Powell

また初日のキーノートスピーチにはとても感銘を受けました。結論としてはツールやライブラリー、言語の思想や構造を理解したうえでそれに沿った使い方をすべき、というものでした。pandas で金融のデータを扱うケースを参考にしつつ、「こういう使い方は間違いだよね」と紹介していくものでした。一番簡単な例を挙げると日時、銘柄、価格のカラムがあるのであれば、日時と銘柄をインデックスにして価格のみをカラムとすべきというものです。

ともかくとして単にツールを使うのではなく、そのツールのもつ思想や目的、内部的な構造を深く理解しようという啓蒙でした。データベースを使うにしても、DuckDBを使うにしても、何にしても「それがどういう内部構造でどういう意図のものか」を理解して適切に使おうというものです。ノウハウ、小手先のテクニックという話ではなく、プリンシパルに帰ろうという技術的な天啓を感じさせるものでした。

トークをたくさん聞けた

今回は私が登壇せず、スタッフでもスポンサーでもなかったので一人の参加者として改めて楽しめました。純粋に参加者として参加したのはPyCon JP 2011以来かもしれません(2012年にはJointイベントでDjango・Pyramidのスタッフでした)。

その中で本当に楽しめるトークが盛りだくさんで良かったです(もちろん上記した以外のトークも素晴らしいものばかり)。もうPythonは15年近くやっていますし、近年はPythonの用途も幅広くなっています。ですがその中でも新しい領域の話や、コア開発・ライブラリー開発に関わるディープなトークもたくさんあり堪能できました。

また、トークの後には質問ができたり、登壇者と直接話す機会があり現地に参加して良かったと思っています。子どもを連れての参加でしたので、イベントの前後の子守もあり正直疲れ果ててしまいましたが、全力で参加できて良かったです。

最後に、今の時代こそ

PyCon JP 2024はトークの内容としてもイベントとしても素晴らしいものでありました。スタッフの皆さまには感謝しております。

今の時代はイベント運営というのが簡単ではなくなったように思います。たくさんの人が関わっており、いろいろな意見、憶測、守るべきことなどが存在する世界です。それも大切なことですし、内省し改善すべきこともあるでしょう。ですがそういったリスクにさらされやすい運営の人たちが「じゃぁもう辞めようか」となってしまうのは悲しいものです。建設的な議論と、前向きな行動が、改めて周囲の僕たちを含めて必要なのかなと思います。

あとポジティブなフィードバックとかね。

今年のPyCon JP 2024はトークの内容もイベントも堪能でき、かつ技術的なディープさもちゃんとありとても良かったです。まぁ、僕のこの「良かったよ」というメッセージは大して多くの人にも見られず、炎上しやすいマイナスの意見が人の心に残りやすいものです。でもだからこそ、今回はきちんと感謝を伝えたいなと思いブログに残すことにしました。

ありがとうございました。

執筆:@hirokiky
Shodoで執筆されました

「ストーナー」を読み終えて

前回書いたように株主総会や決算が終わり、やっとまともな呼吸ができるようになって、ストーナーという小説を読んでいました。途中までほんの少しずつ読んでいたのを、精神的な落ち着きが得られた今になって、一気に読み終えることができました。

本の感想はあまり言いたくないというか、自分の中でもう少し大事にしたい何かがある状態です。なので人におすすめなどはしたくないものの、どんな感想でも見つけ出して自分のものにしてしまえる時代だからこそ、何かを書いておきたい気持ちになっています。おそらくは、読み終えた人の大半はこんな感情になるんじゃないでしょうか。

太鼓判を押したいものでもないですが、自分の中で大切にしたい何かがある本でした。小説(とくに純文学)を読むのも久しぶりといえばそうで、最近はエンジニアや経営者らしく技術書やビジネス書、会計の本などばかり読んでしまっていました。だからこそ、この本を読めて良かったと思いますし、たまたま妻と娘が家にいない貴重な自分の時間をこの本の最後に割けて良かったです。妻子をもつと一人の時間ってものすごく貴重なので、それを読書に使うのはほんとうに贅沢なことですからね。それでも良かったと思っています。

まぁ、これを感想とさせてください。

むしろ結婚し、子どもを育て、そして仕事を頑張るなかでこそ味わえた読了感なのかもしれません。読み終わったときは悲しみというか、何かを失った気持ちになりましたが、今はそれも含めて受容する精神的なプロセスのようなものを感じています。そういう本なんです。

こんな気持ちになった本はサン=テグジュペリの「人間の土地」以来かもしれません。

思えばここ数年は、あまりにも世俗的というか、目的をもって本を読むことや消化することに汚染されすぎていたなと思います(以前もそんな話をしましたが)。この本の冒頭から分かるように、劇的でなくヒーローも登場しなければ、快活でも知見を授けてくれる本でもありません。でもだからこそ、読む価値があったなと思える時間でした。そういえば、こんなにも純粋に活字そのものに心を惹かれたことって最近あったっけ?と思えるほどです。嘘みたいな話ですが、さっき出ていった妻がすぐ帰宅して「忘れ物でもあったかな」と思っていると、もう1時間近く経っていたということもありました。

今、僕の横には「肩をすくめるアトラス」があるのですが、また何か目的主義的というか何らかの悪癖に身を投じる予感がしています。今だけはもう少し、ありのままの世界に浸らせてもらいましょう。

執筆:@hirokiky
Shodoで執筆されました

作った会社の第4期の決算が終わりました

株式会社ゼンプロダクツを創業して4年、第4期の決算と株主総会が終わりました。
前期に続いてかなり良い感じの成長を遂げ、投資をしていただいた2年前に掲げた目標も順にクリアできています。

ほんとうにありがたいことです。

自分で作った会社、プロダクト、サービスでやっていけるだけでとてもありがたく光栄なことです。ですが、ここからさらに倍、倍と成長を求められる(または自分に課していく)のがスタートアップです。ほんとうに大変な世界なので、起業(とくに自社サービスのスタートアップ)なんてやらないほうが良いと思います。

投資していただいた株主の方には満足していただいており、ランチもご一緒しました。でも毎年思いますが、またここからが一番大変な時期だなと思います。正直、ゼロから1を作り、お金をいただくという意味で1から10には成長できたかなと思います(まぁ何をもって「1」や「10」なのかは人によりますが)。ですがやはり次は100や1000を目指していく世界なので、「ほんとうのたたかい」が始まるのでしょう。

株主総会をする僕

ここ最近はPR TIMES様にご導入いただいたり、他の大きな会社さんを始めいろいろな方にもお世話になっています。自分の作った世界(サービス)が世の中に受け入れられることをとても嬉しく思っています。ですがそれと同時に、この厳しい激動の時代を乗り切り、より大きな価値や便利さでお返ししないとなと思っているところです。またさらにリスクを取って、良いプロダクトとして還元できるよう頑張ります。

Make組ブログとしてサービス開発を中心にやってきたブログですが、そのままの姿勢で会社を続けられていることが何よりも嬉しいことです。

執筆:@hirokiky
Shodoで執筆されました

「Xで炎上したのだけ知ってる」という回数を減らしたい

「Xで炎上したのだけ知ってる」というとき、SNSで話題やトレンドだけ追いかけているのにその詳細はまったく知らないし興味もない、ということが多い。それを終わりにしたい。

パリオリンピック 2024が終わった。

僕はクライミングやり投げやレスリングなどを楽しく観ていたのだけど、Xを見るといつも炎上している印象すらあった。個人的にその温度差を感じてしまって、ちょっと怖かった。開会式の演出、選手村の冷房や食事、セーヌ川の汚れ具合、誤審など、問題が指摘されては荒れていた記憶がある。もちろんそれらに問題はあるのだろうけど、侃侃諤諤してる人ほど一番本質的な選手が競技してるさまを観ていないのが異様でもあった。

当該の話題を見ても「メニューにタンパク質が少なく、調理時間もかかる」という話が「あのイギリス人がパリオリンピックの料理を酷評」になっていたり、内容がアレンジされて伝わってる感もあった。そこまでちゃんと読んだとして、スポーツ観戦をして選手を応援することにはならないが、少なくとも記事の内容くらいは正しく理解したほうが良いと思う。もちろん「森選手がボルダー課題でスタートすらできなかった」のは僕も悔しい。でも彼女のリードクライミング決勝の素晴らしさを見ていないことのほうが惜しいと思う。メダルではない輝きがあった。

最近こういうことは多い。

僕もある。でも今回それを感じたという話。

少なくとも知らない話題であったり、本来は興味のない問題であれば論客ぶったり怒ったりする必要はない。現実にも端から急に話題に参加して知ったふうな口と結論を言って去っていく人がたまにいるが、あれにはなりたくない。とくにネットニュースとそれを元にしたツイートは質が低い。ネットニュースはまだ良いと思うけど、それを改行たっぷりにして歪曲して伝えるツイートとか、それへの引用RT、リプライなどはひどい。誰も何も分かってないのに、口から先だけで話して喧嘩してる。

なんだか寂しくもあった。子どものころ週刊誌やワイドショーを見てキレてる老人を見てあぁはなりたくないと思っていたが、そうなりつつある。あるある大事典に踊らされる親世代を笑っていた賢いネットの民が、今や同じ姿になっている。それが悲しい。

まず人として不自然だと思うし、論理的なふりして論理的でもないし、何よりダサいと思う。

それを今回とくに感じた。

なので好きなこと以外に食いついて話題にしないし、興味があればそれをきっかけにちゃんと触れることにする。自分のテリトリーを持って、自分がちゃんと興味あることをちゃんと楽しめるようにしたい。引退もしないしMastdonにも行かないけど、自分の中でトレンドを追わないとか気をつけようと思う。ニュースを知りたいなら日経新聞(あなたが信用できるメディア)を読もう。

「Xで炎上してたよね。普段よく知らないけど」と言わないようにしよう。

執筆:@hirokiky
Shodoで執筆されました

ガリが市営ジムに1年通って体重を7キロほど増やした

やったぜ!って話です。

もともと体重49kgの体脂肪率5%(誤差の範疇なので5%になる)だったのですが、今は56kgくらいに増やせました。

今が人生で一番健康だと思います。

僕は生まれてから30年間ずっと痩せてました。どうしても食えないし、太らないし…、と言うと「ズルい!」みたいな反応をもらいますが当人は真剣に悩んでいました。だってさ、すぐ風邪を引くし寒いし、貧血起こすし虚弱体質だったわけですよ。結構大変なんですよ。機能性ディスペプシアとか逆流性食道炎とかも患ってましたからね。

何度も体重を増やそうとしたもののうまくいかず、やっとうまくいったという話です。良かった。

週2ジム

まぁ何ていうか結局は運動が大事でした。

胃腸科のお医者さんに言われるたびに思いました、「ストレスを減らして運動しろってしか言えないのか!」って。「こちとらストレスと運動不足で稼いどんじゃい!」って、でも発想が逆なんですね、現代人が無駄にストレスを抱えて運動してないのが異常 ということです。運動しなきゃ!じゃなくて、椅子に16時間座ってるのが人類にとっておかしいということです(ハッザ族もよく歩くらしいですし)。

運動というとカロリーを消費するイメージがありますが、まず体力と食欲が必要なので意外にも運動が必要でした。昔、プールに通っていたこともあったのですが、そのときは太りにくかったので筋トレが良いと思います(逆に痩せたいならプールってめっちゃ良いと思う)。

ジム
1年ほど週2でジムに通い、しっかり筋トレをしました。友だちと「ダイエット」Discordチャンネルで励ましあいながら1年ジムに通っていました。まぁ、週2回のうち1回がプールだったり、宅トレだったりのときもあります。あんまり目標を設定しすぎると辛いので、無理しないってやつです。一応、Apple Watchと「俺の筋トレ記録」というアプリで計測しています。

だいたいベンチプレス、チンニングやラットプルダウン、レッグプレスなどの一般的な種目をやっていました。デッドリフトとスクワットは難しいのでやってません。基本はマシントレーニングにするのが、安全で良いと思います。でもベンチプレスは楽しいのでおすすめ。

ジムは市営のジムなので、1回150円のところか200円のところ。なので月に1200円ほどです(市営って良いですね)。ただそれゆえにモチベの管理が大変でした。市営ジムだと「高い金はらった!」って感覚がないので、個人の努力次第という感じ。

たったの週2回だけどがんばって続けたよ…。今は週1.5回くらいの怠けぶりですが、まだ続けています。

食べる

食べました。

始めたのが23年の4月くらいからで、計測は途中からですが線形回帰しています。

体重の推移

途中で落ちているのはインフルエンザになったときです。

結局は食べないと痩せるのはまじです。正直、ジムに通うよりもこっちのほうが大変。ただ食べられない人間が無理に食べると嫌になるものです。

ガリが太るポイントは以下です

  • 食事を抜かない
  • まじでちょっとずつで良いから増やす(おかわりとか、間食とか)
  • カロリー計算をしすぎない
  • 乳酸菌入りのエビオスを飲む

食事を抜かないなどもそうですが、なるべく小さくカロリーを稼ぐのが重要でした。「二郎食うぞ!」となるとそのさき数日体調を崩すので、いたって普通の食事をちょっと気持ち多めに食べました。筋トレしてるのもあり、食えるときは食えるようになってくるって感じです。

とはいえガリにとって 最初の数カ月は筋トレというかリハビリ です。まず健康的な人間になるために2、3ヶ月はかかった感じなので、焦りは禁物ということ。最初はモチベが高いので無駄に色々やったり頑張りすぎるけど、体が追いつかないからやめとけ。

あと意外にも痩せる人間ってカロリーに敏感だったりするんですよね。なので逆にあんまり気にせず、とりあえず食いたければ食うというのが良いと思います。僕もジムの帰りにビッグマックセットにマックフルーリーを足したりできるようになりましたが、とりあえず太るターンのときは食いたいだけ食うのが良いです。

ダーティバルク最高!

結果どうだったか

まじめな話、運動も食事も楽しくなったし、人生がだいぶ好転しました(ギラギラ輝く目)。というか以前は食事が義務的な感じで、楽しめる余裕が少なかったのですが、今は食事にもわりと興味を持てています。

あと外に出ても疲れにくいし、体の芯まで冷える感じがしないなど、今まで自分が「そういうもん」と思っていた不快感が改善しました。まるで老人の悩みが解決したみたいですが…。

とはいえ遺伝子には勝てない感じがあって「食えないものはいまだに食えない」感じがします。友人たちを見ていると今の僕以上に普通の感覚で食っていて、「あぁ、僕は努力してやっと普通の成人男性になれたんだ」と思いました。遺伝子ってすごいですね。

というわけで僕に「痩せてて良いですね」とちょっと皮肉っぽく言っていた人たち、僕はがんばって体重増やしましたし、「1年間、週2回ジムと本気でダイエット」はできたよ!と伝えたいです。体質の改善がどれだけ大変かは僕もよくわかります。一緒にがんばりましょう。

ぜひ 「脚太くなったね!」 とか「背中ぶ厚くなったね。背中の種目何やってる?」とか言ってくれたほうが嬉しいです。

執筆:@hirokiky
Shodoで執筆されました

【募集】DjangoCongress JPの開催地を募集します

こんにちは。今日は少しお願いがあります!

DjangoCongress JPの開催地・会場を募集しています。

例年開催しているDjangoCongress JPですが、次回の開催地と会場がまだ決まっていません。とくに東京以外の場所で「ぜひここでやろう!」という方を求めています。会場スポンサーとしてトーク枠を1つ提供しますので、ぜひ採用や会社のブランディング等にご活用ください。

Djangoはユーザーも多く、業務で使われることもたくさんあるWebフレームワークです。その知見を定期的に交換したり、仕事の紹介ができる場は必要だと思っています。また今回はDjangoに限らず、Pythonでの非同期Webというトークも募集したいなと目論んでいます。

募集要項

背景としてはこういうものです:

  • 東京以外でもイベントをやりたい。以前は長野でやりました
  • 東京以外で開催する場合、現地の熱意ある人(現地スタッフ)が必要
  • DjangoCongress JPは会場のスポンサーのみ募集しているため会場費はほとんど出せない

ありがたいことに東京では会場を貸してくださる企業さんなどはいらっしゃるのですが、東京以外だと少ないのが現状です。東京ばかりでイベントがあるのって悲しくないですか。この機会にどうでしょう?!

会場に求めるものとしてはこのあたりです:

  • 時期は2025年2月ごろ
  • 会場のキャパシティは多くて100人くらい
  • トラック数(部屋数)は理想で2つ、1つでもOK
  • Wifi、電源、投影用のスクリーンがある
  • お昼ごはんを食べに行く場所が近隣にある(会場でのランチ提供はしないため)

応募方法

hirokikyもしくはdjangojaのTwitterアカウントか、django-jaのDiscordにご連絡ください

最後に

お願いばかりになって恐縮ですが、DjangoPythonを今後も盛り上げるためにご協力ください。

もちろん会社の採用に役立つとか、ブランディングになるとかもありますが、一番大切だと思うのはコミュニティへの還元です。僕たちは常日ごろ、オープンソースの恩恵を常に受けています。コミュニティ運営やスポンサーシップというのはとても大切な貢献(コントリビューション)だと僕は思っています。とくに今はコロナ禍が終わって、またもう一度そのコミュニティを作り直す大変な時期です。

ぜひ、賛同してくれる方はお力を貸してください!

執筆:@hirokiky
Shodoで執筆されました

結局、migrate機能ってなぜ必要なの? WebフレームワークのDBマイグレーション機能の意味を解説します

DjangoなどのWebフレームワークにはマイグレーションという機能が搭載されています。ですがこのマイグレーションという機能の必要性が分かりにくい(いまいちピンときていない人がけっこう多い)ので背景を踏まえて説明します。

マイグレーションとは何なのか?

Webフレームワークのマイグレーション機能はDjangoRailsに付属している機能です。

そもそもDBマイグレーションは、すでに本番環境等にリリースされたデータベースを破壊せずに、アプリ側で使いたい新しいテーブルやカラムを追加(もしくは変更、削除)することです。毎回データベースをすべて削除して1から作り直してしまえば「DBマイグレーション」は考えなくて済みますが、そうするとユーザー情報や過去に書いた記事などがすべて消えてしまいます。

そういった問題を解決するため、Webフレームワークなどが「マイグレーション」という機能を提供しています。ですが便利すぎるゆえ、逆になぜ必要なのかも分かりにくくなっています。フレームワークのモデルを書き換えると、なぜかマイグレーションファイルを作ってマイグレーションを実行しろと言われますね。マイグレーションファイルが作れなかったり、なぜかデータベースに適応できなかったりトラブルが起こったりもします。そこで…

マイグレーション、要らないのでは?

消したほうが楽なのでは?

など言われてしまうのですが、そうではありません。めちゃくちゃ便利ですごい機能なんです。

この記事ではマイグレーション機能がない世界でのデータベースの運用を説明し、改めてマイグレーション機能の必要性を理解しようと思います。

マイグレーションがない世界へようこそ

マイグレーション機能がない世界を考えてみましょう。

まずモデルとしてはこういったユーザーの情報を考えます。

class User(models.Model):
    name = models.CharField(...)

無事にアプリを本番リリースし、以下のようなデータベースが動いていると考えましょう。ユーザーのテーブルがあり、IDとユーザー名が管理されています(IDフィールドは勝手に作られます)。

このテーブルがアプリ上のUserモデルに対応しているわけですね。

ここで新機能として「自己紹介欄」を追加したくなりました。Djangoのモデルで言うと、この2つ目のフィールドを追加した状態にします。

class User(models.Model):
    name = models.CharField(...)

    # ↓↓↓ このbioをアプリに追加 ↓↓↓
    bio = models.CharField(...)

この場合、最終的には以下のようなテーブルがデータベース上に必要となります。最初は bio に何も入っていなくても良いですが、ユーザーが好きに自分のことを書けるようにしたいわけです。

さてプログラム的には bio というカラム(モデルのbioフィールド)を利用するよう書き換えたわけですが、今すでに存在しているデータベースには bio というカラム(フィールド)がありません。

プログラム上は bio を使うように書き換えたのに、本番データベースにはそのカラムがないわけです。これは困りました。データベースを一旦削除して再度作り直すと、せっかく集めたユーザー情報も消えてしまいます。

ここで以下の3点がポイントになります:

  1. データベース(RDB)側のテーブル定義を変更しないといけない
  2. プログラム上の「Userモデル」等を書き換えても自動的にデータベースは変わらない
  3. データベースを変更しないままアプリがbioを使おうとするとエラーになる

これはMySQLPostgreSQLなどのリレーショナルデータベースがテーブルの定義(データ構造)をしっかり決めてデータを管理するデータベースだからです。アプリ側で bio というデータを使いたいとなった以上、データベースに変更が必要です。

データベースにカラムを追加するにはどうすれば良いでしょうか? 正解は ALTER TABLE ... ADD とカラムを追加するSQLをデータベースに実行することです。

このSQLを実行するとデータベース上に bio カラムが作られ、bio を使うアプリをリリースしても正常に動作するというわけです。これがDBマイグレーションの基本的な考え方です。

SQLを管理する

さてこの ALTER TABLE ... ADDSQLを実行すべきなわけですが、アプリを書き換えたタイミングでこのSQLを用意しておく必要がありますね。

class User(models.Model):
    name = models.CharField(...)
    
    # ↓↓↓ このbioをアプリに追加した時点で、更新用のSQLが必要になる ↓↓↓
    bio = models.CharField(...)

そこでこの変更を加味して、SQLのファイルを作っておくことにしました。こうすれば他の人が見ても「リリース時にSQLの実行が必要なんだな」と分かりますし、自分でも思い出せて便利ですね。

0002_user_bio.sql というファイル名で作っておきましょう。

ALTER TABLE user
ADD bio VARCHAR(200) DEFAULT '' NOT NULL;

このSQLmigrations というディレクトリーに入れておくことにしました。ついでに、データベースを作る際に実行したSQL0001_initial.sql として置いておきましょう。

migrations/
    - 0001_initial.sql
    - 0002_user_bio.sql

これでOKです!

こうしてデータベースの変更をSQLとして管理し、Webサービスを運営していくことができました。

自前の管理で起こり得るトラブルは何?

実際に昔はWebフレームワークのDjangoにはマイグレーション機能がなく、このようにSQLを保存して管理したりしていました。SQLで管理していれば良いほうで、その場その場でSQLを書いて間違えてしまったりもありました。

どういった問題が起こるのでしょうか。こういったことが考えられます:

  • どこまでマイグレーション用のSQLを実行したか分からなくなる
  • モデル(テーブル)の変更内容と違うSQLを書いてしまう
  • 書くべきSQLがデータベースの種類ごとに少しずつ違う
  • そもそもDBマイグレーションを管理しておらず各データベースの状態が分からなくなる

昔はけっこうこういった問題があり、うんうんうなりながら何とかしたわけです。

そこで登場するのがマイグレーションという機能です。Djangoでは先に South というマイグレーション用のツールが登場し、一般的に使われるようになりました。その後、このSouthの開発者を中心にDjangoマイグレーションという機能が組み込まれていきました。

マイグレーション機能が解決することは?

マイグレーション機能のポイントは以下です:

  1. モデルの変更を検知して、自動的にマイグレーションファイルを作成する
  2. マイグレーションファイルからSQLが作られ、データベースに変更が適応される
  3. データベースごとにどこまでマイグレーションを実行したか履歴を管理する

さきほどSQLで管理していた migrations/0002_user_bio.sql などは migrations/0002_user_bio.py というものに置き換わります。ですが内容はまったく同じです。このマイグレーションファイルを自動で生成してくれるので、自分で適応すべき変更差分を書く必要がありません。また、使っているデータベースの種類に応じて、SQLも適切に書き換えてくれます(SQLを直接生成しないのはこのため)。

またDjangoマイグレーション機能はデータベース自体に「どこまでマイグレーションを実行したか」の履歴を保存しておいてくれるので、 python manage.py migrate と実行するだけでデータベースごとに必要な変更が取り込まれます。django_migrations という自動で作られるテーブルで管理されており、マイグレーションを実行したタイミングで適応済みの履歴も自動で更新されます。

つまり、SQLで管理していたような作業をすべて自動でまかなってくれるということです。Djangoではこういった仕事が必要となることを見越して、機能として提供しています。

おさらいするとこうなります:

Djangoマイグレーション系のコマンド

ここでDjangoが提供しているコマンドを見てみましょう。先ほどSQLで管理していた例を思い出しながら、各コマンドが何をしてくれているかを理解しましょう。

makemigrations

モデルの変更を検知してマイグレーションファイルを作成します。マイグレーションファイルは上記したような「変更を管理するSQL」と似たものです。

たとえばユーザーに bio のフィールドを足すと、 migrations/0002_user_bio.py のようなファイルが生成され、これが ALTER TABLE ... ADD bio ... というSQLに相当します。

migrate

DBマイグレーションを実行します。対象のデータベースからまだ適応されていないマイグレーションファイルを検知して、マイグレーションファイルからSQLを生成し、データベースにSQLを適応します。

migrate --plan

現在対象のデータベースに対して、これから実行されるであろうマイグレーションの内容を表示してくれます。

migrate --fake

マイグレーションの変更を適応せず、実行履歴のみ「適応したこと」として更新します。すでに別の方法で変更が取り込まれている場合などに実行します。

showmigrations

管理されているすべてのマイグレーションと、どこまで適応されたかの状況を表示します。

sqlmigrate

指定されたマイグレーションファイルをSQLにして表示します。SQLで管理する例であげていたような ALTER TABLE ... ADD などのSQLです。対象になっているデータベースに応じてSQLの方言もあわせます。

squashmigrations

指定された複数のマイグレーションを1つにまとめます。まだ適応されていないマイグレーションが複数ある場合に、このまとめられたマイグレーションを実行するだけで済むようにします。

他にも湧いてくるであろう疑問と答え

話としてはだいたい終わりました。

ここで、これまでの説明を踏まえて湧いてくるであろう疑問に答えておきます:

  • まだ本番データベースなどを管理していないのに migrate しろと言われるのはなぜ?
    • ローカルで開発中に使っているデータベース(SQLite)などの更新に必要です
  • 本番にリリースしていない場合、マイグレーションファイルは必要?要らなくない?
    • ローカルのDBの管理もあるので使っておくと良いです
    • 慣れないうちはマイグレーションファイルを下手に削除したりいじったりしないほうが無難です
  • makemigrations したときに one-off default どうこうと質問されるのは何?
    • カラムを追加するときに既存DBでの値をどうするかを聞かれます
    • フィールドにデフォルト値等があればその値になりますが、ない場合は一時的なデフォルト値が必要と言われています
    • 今回の bio であればデフォルトで空文字やNULL可能としておけば自動で空文字やNULLが入れられます
  • 開発中にマイグレーションファイルが大量にできてしまいます
    • squashmigrationsコマンドでまとめることができます
    • 慣れていれば、開発ブランチで適応された変更をまとめたマイグレーションに自分で作り直すのも可能です(ローカルのSQLiteの変更履歴も操作が必要です)
    • ファイルの数が極端に多くなる場合は、もう少しモデルの設計をじっくり考えてから開発したほうが良いかも
  • 本番データベースにマイグレーションを適応するタイミングはどうすれば良い?

おわりに

今回はざっくりとDBマイグレーションについてとWebフレームワーク等が提供するマイグレーション機能の意味を説明しました。Webフレームワークやツールが便利になるごとに、なぜそれが必要なのかは逆に分かりにくくなってしまいます。ですがこうして背景を一つひとつ理解していくことで、その意味をお伝えできると嬉しいです。

執筆:清原 弘貴 (@hirokiky)、レビュー:清原 弘貴 (@hirokiky)
Shodoで執筆されました