はじめに
こんにちは。コミューンでソフトウェアエンジニアをしているU2です。
今回は commmune の開発でも使用している typescript-sequelize のモデル定義ファイルからER図を作成していきます。
背景
commmune は豊富な機能を持ちそれに合わせいくつものデータを保持しているので、永続化のためのテーブルが多く存在します。
また、テーブル定義としてはリレーションを持つが、Sequelizeのロジック上使用しないことが理由でモデルファイルにそのリレーションが記述されていないこともあります。
そのため、新規参入者がテーブル全容を把握するのに苦労しています。(そもそも長く開発に関わっている人でも知らないテーブルがあったりする。)
そんな問題を解決するために、Sequelize のモデル定義ファイルからER図を作成しよう!というテーマになります。
実装の大部分は sequelize-erd github.com を使用させていただいております。
本記事のサンプルコードはこちらです。 github.com
やりたいこと
- sequelize-typescript に sequelize-erd を適用
- CIでキックし、ER図作成を自動化
実装
環境
- "typescript": "4.9.4"
- "sequelize": "6.27.0"
- "sequelize-typescript": "2.1.5"
前準備
対象となるモデルファイルと sequelize インスタンス生成ファイルを配置します。
モデルの中身は sequelize-typescript の Sample を利用しています。
database ├── models │ ├── Post.ts │ └── User.ts └── sequelize.ts
フォルダ構成に合わせて適宜参照を変更します。Sequelize の dialect は今回 mysql
とします。
次に、sequelize-erdから
graphvis.js
index.js
sample.js
visRenderer.js
をコピーします。
scripts └── erd ├── graphvis.js ├── index.js ├── sample.js └── visRenderer.js
sequelize-erd
が参照しているライブラリと合わせ、必要なパッケージをインストールします。
$ npm i typescript ts-node sequelize sequelize-typescript lodash commander
npx tsc --init
で tsconfig を生成したら事前準備完了です。
実験
ER図の生成
sample.js
を generate.ts
にリネームし、参照を import に修正します。
トランスパイルエラーが出ているので一旦 tsconfig.json
に追記し対応します。
"noImplicitAny": false
この状態で sample を実行してみると
$ ts-node scripts/erd/generate.ts /sequelize-erd-sample/node_modules/sequelize/src/dialects/abstract/connection-manager.js:81 throw new Error(`Please install ${moduleName} package manually`); ^ Error: Please install mysql2 package manually ~~~
パッケージ不足のエラーが出ました。sequelize の dialect を mysql
にしているため、mysqlパッケージをインストールする必要がありそうです。dialect を sqlite にしている場合、sqlite3
のインストールを求められます。
素直にインストールし再実行します。
$ npm i mysql2
$ ts-node scripts/erd/generate.ts
すると、プロジェクトルートに svg ファイルができています。成功です!
CI化
次にCIに載せていきます。今回はGithub Actionsを使っていきます。
最初に pakcage.json
にER図生成コマンドを設定します。
"scripts": { "erd:generate": "ts-node ./scripts/erd/generate.ts" }
次に .github/workflows/gen-erd.yml
を追加します。
ymlファイルはこちら
github.com
アクション内の値をグローバル変数にセットする際に利用する set-output
が2022/10 から非推奨になったようなので
github.blog
代わりに、推奨されている $GITHUB_OUTPUT
を使用してみています。
run: | git status --porcelain | wc -l file_count=$(git status --porcelain | wc -l) echo "file_count=$file_count" >> $GITHUB_OUTPUT
Github Actions が成功していて
github actions が svgファイルをコミットしていることが確認できました!
実験は成功です!
今後の課題
sequelize-erd が OSS として公開されているため、汎化できそうな切り口を考え fork して公開できるようにしていきたいと考えています。
それから、実際に運用しているテーブル数はかなり多く、ユーザテーブルのような様々なテーブルとのリレーションを持つテーブルが存在するため、1つの画像ファイルとしてER図にすると見辛くなってしまいます。
テーブル全体像の把握やPRのレビュー時のことを考えても、テーブルの系統毎に分割してER図にする必要がありそうです。
(実際のモデル定義ファイル群からER図を生成した一部です)
こうしてみると独立したテーブルが散見され、おそらくモデル定義にリレーションを記述していないファイルも多く存在しそうです。
これら独立したテーブルを見て、モデル定義の情報拡充を進めていきたいです。
また、今回は sequelize-erd のコードをscriptsファイルとして配置してしまいましたが、外部ライブラリとして切り離せないかも検討したいところです。
参考サイト
sequelize-erd github.com models file github.com github actions devblog.thebase.in deprecating set-output github.blog
まとめ
運用中のサービスでER図を手動メンテはしたくないが、ER図はあると何かと便利、それなら自動化しようという試みでしたが、概ね上手くいきました。
モデルファイルの追加・更新に対してER図もそれに追随するようになるとPRレビューもしやすくなりそうなので導入を進めていきます。
typescript-sequelize のモデルファイルからER図を自動生成する第一歩を踏み出せたと思います。
次回、fork編
前回同様、今回も業務時間のうち20%を好きな技術課題に当てられる制度を利用して実験を行いました。
前回記事はこちら
tech.commmune.jp
制度についてはこちら
tech.commmune.jp
プロダクトロードマップに乗るような大きな課題から、明日の開発体験を向上させる小さな課題まで、主体的に取り組める環境です!(PRです)
We are hiring!!