DjangoCongress JP 2023に参加しました #djangocongress

2023年10月7日、[DjangoCongress JP 2023](https://djangocongress.jp/)に参加しました。今年の会場は[サイボウズ株式会社](https://cybozu.co.jp/)さんでした。

![E9E9CA75-FB91-45DE-8FB3-BE3196A270CB.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/7809/5dbd96e9-32a5-9adf-1086-7680bc09e6cd.jpeg)

## Djangoアプリケーション運用のリアル：問題発生から可視化、最適化への道
スピーカーは吉田花春さん。

リリース後に不具合対応することになったが、調査するための材料が足りなくて困ったことがあったので、同じような体験をしている人と情報を共有したいというのが発表の動機とのことです。

主に以下の改善点について解説していました。

1. エラーやログを取得する
1. APM（Application Performance Monitoring）を活用してボトルネックを解消する
1. カスタムメトリクスを計測して、問題の原因を把握できるようにする

### エラーやログを取得する
ログメッセージは出力自体をやっていない、もしくは出力しているけど原因調査の役に立たないことがよくあったため、以下のように設計したとのことです。

- ログレベル（CRITICAL、ERROR、WARNING、INFO、DEBUG）を使い分ける
- APIリクエストのstart/end時にログを出力
- 5W1Hがわかるログメッセージを出力（「いつ」「どこで」「なぜ」「何が起きて」「何をすればいいのか」）

また、RuffやFlake8拡張を使って不適切なログメッセージがないか検証できるそうです。
ERRORやWARNINGがあったらSentry経由でSlackに通知が届いて原因把握と対策の検討を迅速に行えるようにもしたとのことです。

### APM（Application Performance Monitoring）を活用してボトルネックを解消する
アプリのどこが重いかわかるようにしたいという意図で、以下を導入したとのことです。

- APM
    - SentryのPerformance Monitoring
    - DatadogのAPM
- CloudWatch Logs Insightで使ったログデータの分析
    - スロークエリの発見

### カスタムメトリクスを計測して、問題の原因を把握できるようにする
メトリクスはあるが原因は不明なケースを防ぐには、カスタムメトリクスを作成するのが有効とのことです。
[python-json-logger](https://pypi.org/project/python-json-logger/)を使ってJSONでログを出力し、Datadogでカスタムメトリクスを作成したそうです。

運用しやすい設計をどうすべきかという話は、一回痛い目を見て学習する側面があるので、こういう実体験に基づく話はありがたいですね。

## グラフデータベースを用いたDjangoアプリ作成入門
スピーカーはAkinoriさん。

Neo4jというグラフデータベースをDjangoから利用した際のノウハウについてのお話でした。
グラフデータベースとはデータ同士の関連をグラフで表現するデータベースで、以下のメリットがあるとのことです。
1. 複雑な現実世界を表すのに最適である
1. 未知の問題への迅速な対応力をもっている

RDBだとパフォーマンスに問題が出るような設計でもグラフデータベースだと快適に使える

DjangoでNeo4jを利用するには[neomodel](https://neomodel.readthedocs.io/en/latest/)（Neo4jのPythonインターフェイス）、[django_neomodel](https://github.com/neo4j-contrib/django-neomodel)（Djangoでneomodelを使うための拡張）を使うそうです。
実際のコードを見せてもらったところ、RDBを使う場合に近い書き方でモデル定義ができていました（ただし、マイグレーションファイルは作られない）。
adminからも利用できるので、RDBを使った場合とほぼ同じことができるようです。

グラフデータベースはRDBに完全に取って代わるようなものではないものの、アプリケーションの要件によっては可能性を感じさせるデータベースだと思いました。
なにより、データ同士の関連をGUIで確認しているデモを見るだけでも楽しそうでした。自分でもアプリを作って試してみたいですね。

## Django初心者が中級者になるために知るべきこと
スピーカーはHiroki Kiyoharaさん。

Djangoのチュートリアルをやってみたのはいいものの、更に上のステップを目指すにはどうすればいいかわからない人に向けたノウハウのお話でした。
主に以下について話されていました。
- 設計
- テスト
- デプロイ

### 設計
作り始める前に作りたいものを具体的に考えるのが大事。
DDDのような設計手法を覚えましょうという話ではなく、どんな機能があるのか、どんな画面が必要なのかなどを考えておこう、と話されていました。
画面が思いつかないときは似たサービスの画面やURLの構造を参考にするのもお勧めとのこの（ただし、公開するサービスで露骨に丸パクリするのは良くないので個人用の非公開サービスで勉強のために真似ると良い、という意味）。
設計はモデルを中心に考える。モデルが一度設計を決めると大幅に変更するのは難しいので、しっかり考えたほうがいい。モデル設計を考える過程で要件にマッチした適切な名前を考えられるとのことでした。

### テスト
まず、公式ドキュメントの[自動テストの導入](https://docs.djangoproject.com/ja/4.2/intro/tutorial05/)に従うのが良いとのことでした。
サードパーティのpytest-djangoもお勧めとのことでした。
また、テストしやすい設計にするには、Viewにロジックを書きすぎないほうがいいそうです。

### デプロイ
デプロイは以下についてできるようしなければならず、`runserver`コマンドでローカルでアプリケーションを使うのとは違う観点があるとのことです。

1. インターネット越しに使えるようにする
1. 安全に使えるようにする
1. 安定的に動くようにする中長期的に管理、運用しやすくする

趣味アプリならとりあえず最低限必要なことだけやって、後から少しずつ学んでいけばよいとのことでした。

ウェブアプリケーションは覚えることが多いですが、とりあえず動かせるものを公開して成功体験を積むのも必要なので、学ぶ内容も優先順位を付けるのが大事だなと思いました。

## Django ナレッジ共有　～DB管理は別の部署 & 開発tips～
スピーカーは松野 一貴さん。

松野さんの職場ではデータベースがフロント・バックエンドで別れており、バックエンド側DBは別部署が管理しているため、`migrate`ができないとのこと。

`settings.py`の`DATABASES`にフロント系のDB情報とバック側（別部署が管理）のDB情報を共存させ、
`migrate`ができないバックエンド側DBには`inspectdb`コマンドを使ってテーブル定義を元にモデルを出力させるようにしたとのことです。

Djangoから接続するデータベースを切り替える方法は以下の2通りあって、`2.`を採用したとのことです。

1. `db_manager`で接続するデータベースを変更する
1. Database routerを設定してモデルごとに接続するデータベースを変更する（参考URL: https://tokibito.hatenablog.com/entry/20160202/1454344534）

また、バックエンド側DBがFKを使わないというルール（？）で運用しているため、モデル定義を工夫する必要があったそうで、なかなか強烈な体験をされていますね :sweat: 

## django migrationで学ぶデータベース設計
スピーカーはaodagさん。

スキーマ変更の実行コストは以下のように変更内容によって大きく変わるため、いかに実行コストが低い設計にするかが重要とのことです。

- メタデータの変更のみ→一瞬で終わる
- データ更新→インデックスの追加、カラムの（末尾への）追加はwrite lockがかかる
- テーブル再構築→主キーの変更、カラム削除、カラムのデータ型変更、NOT NULL, NULL制約の変更、カラムサイズの大幅な変更はテーブルコピーがかかる

スキーマ変更の実行コストを小さくするには、以下について考慮する必要があるとのこと。

- テーブルを小さく保ってスキーマ変更時の実行コストを低く、変更の影響範囲を小さく
    - 正規化（第一正規化、第二正規化、第三正規化）
- 依存関係を簡潔なものにして、そのデータを触るDjangoアプリケーションを減らす
- 小さく恥ずかしがりなデータ

また、Djangoアプリケーションの設計は以下を参考にして行うと良いとのことでした。
- ユースケース駆動
- ドメインオブジェクト
- [オブジェクト指向設計原則(SOLID)](https://ja.wikipedia.org/wiki/SOLID)

O/Rマッパーを使っているとは言ってもデータベースやSQLの知識が必要なくなるわけではないので、自分が使っているRDBについてはしっかり勉強しておこうと思いました。

## GraphQLライブラリStrawberryのDjangoプロジェクトへの適用事例: 実践から学ぶヒントと戦略
スピーカーはMiyashita Yosukeさん。

PythonのGraphQLライブラリ[Strawberry](https://strawberry.rocks/)をDjangoプロジェクトに採用した際の知見についてのお話でした。

StrawberryはDjangoモデルをベースにGraphSQLのTypeを定義する機能があるので、Djangoに組み込むのは難しくないとのことです。

Strawberryの選定理由として以下を挙げていました。
- 開発が継続している
- コードファーストである
    - 既存の実装を活かしたい
    - ゼロからスキーマを書くより生産性が高そう

スキーマ設計でRESTとは違う点としては以下があるそうです。
- 大きなAPIにすることを恐れない
    - 現状ユースケースがなくても元モデルの全フィールドを返すTypeにしておく(もちろんセキュリティ上非公開にしたいフィールドは除外する) 
    - クライアント側で取得するフィールドを選択できるので、大きいAPIでも問題ない
- 関連オブジェクトはネストさせる
    - 関連するIDだけでなくオブジェクトそのものを返す
- 安易にQueryを定義せず、Typeのフィールドにすることを検討する

テストに関しては、GraphQL層に直接ロジックを書かないことでGraphQL層自体を単体テストの対象から除外しているそうです。

また、GraphSQLはN+1問題が起こりやすい問題がありますが、今のところ大きな問題にはなっていないとのこと。

私の今までの開発経験はAPIはすべてRESTだったので、GraphQLならではの知見は興味深いものでした。

## Lightning Talks
最後はLTが３つありました。
![IMG_0844.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/7809/1e927bdb-a256-a23e-7d1c-ab691dcd23dd.jpeg)
カンファレンス参加の敷居を低くしよう、カンファレンスの良さを言葉にしよう！という話。

![IMG_0845.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/7809/0c056ad1-07c8-306b-45fa-609c6f171366.jpeg)
メンバーが多いDjangoプロジェクトで効率よく開発を回すためのDDDに基づいた設計をしているという話。

![IMG_0846.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/7809/43ff9312-6726-4024-29b9-7f5fe959e1eb.jpeg)
結婚式の招待状をWebでおくるサービスをDjangoで作ってみた話。

## クロージング
最後はクロージング。
![IMG_0847.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/7809/879031bb-5ddf-474b-0c31-5b11ae97f69e.jpeg)
![IMG_0848.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/7809/b54ab509-2e30-a3f0-ff43-5894560a875b.jpeg)
![IMG_0849.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/7809/06d47ae1-307c-292f-e6ad-e1fbfd052aeb.jpeg)

## パーティー
今年は会場内でパーティがありました。お洒落な料理とお酒を交えつつ、みんな盛り上がっていました。
![3996F3CC-C725-4ED2-AD6B-1C91D672A18C.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/7809/5f3b65c4-9cc5-5706-b089-71a802533d22.jpeg)

## 最後に
これで今年のDjangoCongress JPは終了です。やはりオフラインイベントにはオンラインにはない独特の雰囲気があって楽しいです。
思えば、20数年前に未経験でITエンジニアを目指した当初、この業界の横の繋がりの強さに驚いたものです。
会社組織の関係がない人たち知見を共有し合う文化に触れたことが、いろんな場面で私を救ってくれたような気がします。
コロナ禍で一旦今までの流れが途切れてしまったかもしれませんが、またオフラインイベントの勢いが戻ってきた今、若い世代もこの雰囲気を体験してほしいです。
尻込みする気持ちはわかりますが、ITコミュニティは初心者を歓迎する姿勢の人が多いので、あまり心配しなくても大丈夫です。ぜひ、遊びに来てほしいですね。
ちなみに、10月27日、28日は[PyCon APAC 2023](https://2023-apac.pycon.jp/)があります。チケットはちょっと高めですが値段に見合う体験はできるので、都合が合う方はぜひご参加ください！

![IMG_0853 2.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/7809/f5bff907-713b-b8ec-669c-72626439ca27.jpeg)

というわけでみなさんお疲れ様でした。また来年！