こんにちは、システム部の能勢です。昨年の秋に入社して、今はバックエンドを中心に開発を担当しています。
「この設計資料、最終更新何年前やねん」
「なんか現実と違うんですけど」
こんな言葉にビビビっとくる方いませんか?
最近はかなり激減したんですが、自分は少なくともエンジニアキャリアの最初の方ではこういう経験をよくしてきたタイプです。
弊社みたいにプロジェクトリリース前にドキュメントを第三者視点できっちり確認されるような体制のある開発現場ではこういうことが起こるのも低頻度だと思うんですが、実際問題世の中にはいろんなタイプの現場がありますし、そこまできっちり管理しきれない・・・こんなホンネが漏れるのが実情という方も多いんじゃないでしょうか。
そこで状況改善の一手として、以前の会社で管理業務をしていた時に自分が探し出して取り入れたDB系ドキュメントまるっと自動生成してくれるツールを紹介、という感じです。さらにそれだけじゃなく、M1Mac環境やデフォルトでは接続エラーになっちゃうMySQL8.0にも対応させています。
「この記事に出会えたことで開発体験爆上がり☆」
こんな仕上がりにしたつもりなので最後までお付き合いください。
それではいってみましょう!
SchemaSpyとはなんぞ。
ツール紹介
今回ご紹介するのはSchemaSpyというツールです。別にどこぞの会社の回し者とかそっち系ではないです。オープンソースで誰でも自由に導入できるのでご安心を。
ざっくり要点だけまとめると、Javaで動くDB関連ドキュメント自動生成ツールです。
カラフルなテーブル定義書を作ってくれたり、外部キーからテーブル間の関係を推測してER図を作成してくれるかなりの優れものです。
「ああ、Javaなのか。(俺Gopherだし環境構築するのダルいなぁ)」
と思ったそこのあなた。自分も環境構築はダルいなーと思っちゃうタイプなので実務でも個人開発でも基本的に全部自動化してます。そんな感じで環境構築なしで動くようなコードを紹介していくのでご安心あれ。
前提
2022年時点で、開発業務で当たり前にDocker使ってる現場がさすがに多数派になってるはずなので、以下の前提をもって「環境構築なし」という言葉を使ってる点だけご容赦ください。
・Dockerがインストールされてて、基本的な使い方は理解してること
ここまで言えばどんな成果物が出来上がるか、うすうすわかってくる方もいると思うんですが、docker-compose.ymlにSchemaSpyを入れちゃおうというのが結論です。
実際に作ってみる。
ディレクトリ構成
今回のディレクトリ構成はこんな感じです。基本的に全部完コピすれば動くようになってます。
project/
├ initdb.d/
│ └ 01-init.sql
├ schemaspy/
│ ├ Dockerfile
│ └ schemaspy.properties
├ docker-compose.yml
└ Makefile
docker-composeの設定
M1Macに対応するべく、MySQLについてはoracleイメージを採用しています。
SchemaSpyの方は最新のバージョンがMySQL8.0に対応していなかったり、M1Macに対応していないといった状態なので独自にDockerfileを作ってビルドするようにしています。
[/docker-compose.yml]
version: "3.9"
volumes:
db-store:
services:
db:
image: mysql:8.0-oracle
volumes:
- db-store:/var/lib/mysql
- ./initdb.d:/docker-entrypoint-initdb.d
environment:
- MYSQL_DATABASE=my_database
- MYSQL_ROOT_PASSWORD=root
- MYSQL_ROOT_HOST=%
schemaspy:
build: schemaspy
volumes:
- ./output:/output
MySQL8.0とM1Macに対応したSchemaSpyのイメージ
いろんなエラーに出くわすので今回ひと工夫加えたイメージがこちらです。
platformにamd64を指定して、mavenからMySQL8に接続できる最新のjarファイルを持ってきてます。この時、rootユーザを指定していないとドライバーを探せないエラーに遭遇するので気を付けてください。
[/schemaspy/Dockerfile]
FROM --platform=linux/amd64 schemaspy/schemaspy:6.1.0
ENV TZ=Asia/Tokyo
USER root
COPY schemaspy.properties .
ADD https://repo1.maven.org/maven2/mysql/mysql-connector-java/8.0.30/mysql-connector-java-8.0.30.jar \
/drivers/mysql-connector-java-8.0.30.jar
schemaspyの方の設定は他のサイトにもよく載っているような至ってシンプルなものですが、ドライバーだけ上でADDしたバージョンを指定してます。
[schemaspy/schemaspy.properties]
schemaspy.t=mysql
schemaspy.dp=/drivers/mysql-connector-java-8.0.30.jar
schemaspy.host=db
schemaspy.port=3306
schemaspy.db=my_database
schemaspy.s=my_database
schemaspy.u=root
schemaspy.p=root
schemaspy.implied=true
schemaspy.norows=true
schemaspy.nopages=true
テーブル初期化用のSQL
そこそこリレーションの多そうな定義のいいアイデアが浮かんでこなかったので、ネットに転がってるポケモンのテーブル設計を頑張ってた方のアイデアを一部借りました。(ありがとうございます)
[01-init.sql]
CREATE TABLE pokemon (
id INT NOT NULL PRIMARY KEY AUTO_INCREMENT,
name VARCHAR(255) NOT NULL
);
CREATE TABLE type (
id INT NOT NULL PRIMARY KEY AUTO_INCREMENT,
name VARCHAR(255) NOT NULL
);
CREATE TABLE waza (
id INT NOT NULL PRIMARY KEY AUTO_INCREMENT,
name VARCHAR(255) NOT NULL,
type_id INT NOT NULL,
FOREIGN KEY (type_id) REFERENCES type(id)
);
CREATE TABLE pokemon_type (
id INT NOT NULL PRIMARY KEY AUTO_INCREMENT,
pokemon_id INT NOT NULL,
type_id INT NOT NULL,
FOREIGN KEY (pokemon_id) REFERENCES pokemon(id),
FOREIGN KEY (type_id) REFERENCES type(id)
);
CREATE TABLE pokemon_waza (
id INT NOT NULL PRIMARY KEY AUTO_INCREMENT,
pokemon_id INT NOT NULL,
waza_id INT NOT NULL,
FOREIGN KEY (pokemon_id) REFERENCES pokemon(id),
FOREIGN KEY (waza_id) REFERENCES waza(id)
);
(おまけ)最後にMakefileでコマンドを短くする
Macなら標準でmakeコマンドを使えますが、WindowsでもMake for Windowsを入れてパスさえ通せば使えるのでぜひ使用してみてください。
Dockerで開発やってると何かとコマンドが長くなりがちなので、いちいちコピペするよりこっちの方がスマートです。最近の同世代のGitHubリポジトリとか見ているとけっこうな方がdockerとMakefileを併用しているのかなと思ってます。
[/Makefile]
.PHONY: db-up db-down ss-build ss-run
db-up:
@ docker-compose up -d db
db-down:
@ docker-compose rm -fsv db
ss-build:
@ docker-compose build --force-rm schemaspy
ss-run:
@ docker-compose run --rm schemaspy
ER図とテーブル定義書を自動生成
DBを起動する
$ make db-up
SchemaSpyのイメージをビルドする
$ make ss-build
SchamaSpyを実行する
ドキュメントの自動生成を行います。
$ make ss-run
ドキュメント完成
テーブル一覧・詳細やER図など、スキーマ内の情報が全部そろった静的ファイルが生成されます。/output/index.htmlが本体です。
最後に
今回はテーブル定義書、ER図をM1Mac環境で自動で作成する方法をまとめてみました。
弊社ではこのフローをGithub Actionsに入れて、S3バケットに静的ファイルをホスティングというとこまでやって、常に最新のドキュメントが見られる状態になっています。
いろんなサービスを提供していたり内部のマイクロサービスが多かったりすると、あちこち資料を探すのも一苦労なので入社当初に自分が提案したものだったんですが、思いのほかあっさり受け入れてもらえたのでその後のキャッチアップがものすごくはかどった思い出ありです。
こんな感じで新しい風も積極的に取り入れてるようなところなので、エンジニアの業務改善をどんどん進められるような方をもっと増やして一緒に働きたいな~とゆるゆる宣伝だけしてこの記事を締めようと思います。
