はじめに
メタップスアドベントカレンダー第23日目です。
開発をしているとドキュメントを見ている時に 「あれ? 仕様と実装がちょっと違う??」 「このドキュメントが最後に更新されたのいつだろ??」 という状況に陥った経験がある方はいらっしゃるのではないでしょうか。
私は過去にRDBのリレーションを視覚的にパッと把握するためのドキュメントが見つけられない経験がありました。そこで、今回はSchemaSpyを使ってER図を自動生成する方法を試してみました。
SchemaSpyとは
データベースの情報を元に、ER図、テーブル、カラムなどの情報をHTML形式のドキュメントとして出力するツールです。
検証
Railsアプリ、MySQL、SchemaSpyをコンテナ上で動かし、MySQLの情報をSchemaSpyで読み込み、ER図を作成していきます。SchemaSpyには docker imageを使用します。最終的なディレクトリ構成はこのようになります。
project
├ app
├ db
├ schemaspy
│ ├ output # 自動生成されたものが出力される箇所
│ ├ DockerFile
│ └ schemaspy.properties
├ DockerFile
└ docker-compose.yml
環境
- Rails 7.0.4
- ruby 3.1.2
- MySQL 8.0
- schemaspy 6.1.1-SNAPSHOT
検証用アプリの作成
まずは簡単なRailsアプリを作成していきます。
プロジェクト配下にDockerFile
とdocker-compose.yml
を作成します。
FROM ruby:3.1.2
RUN apt-get update -qq && apt-get install -y nodejs yarnpkg
RUN ln -s /usr/bin/yarnpkg /usr/bin/yarn
RUN mkdir /app
WORKDIR /app
COPY Gemfile /app/Gemfile
COPY Gemfile.lock /app/Gemfile.lock
RUN bundle install
COPY . /app
COPY entrypoint.sh /usr/bin/
RUN chmod +x /usr/bin/entrypoint.sh
ENTRYPOINT ["entrypoint.sh"]
EXPOSE 3000
# Start the main process.
CMD ["rails", "server", "-b", "0.0.0.0"]
version: '3'
services:
mysql:
platform: linux/x86_64
image: mysql:8.0
volumes:
- ./tmp/db:/var/lib/mysql
environment:
MYSQL_DATABASE: app_development
MYSQL_USER: root
MYSQL_ROOT_PASSWORD: pass
TZ: 'Asia/Tokyo'
ports:
- "3306:3306"
web:
build: .
command: bash -c "rm -f tmp/pids/server.pid && bundle exec rails s -p 3000 -b '0.0.0.0'"
volumes:
- .:/app
ports:
- "3000:3000"
depends_on:
- mysql
DockerFile
とdocker-compose.yml
の準備ができたらrails new
コマンドを実行してアプリを作成します。
docker-compose run --no-deps web rails new . --force --database=mysql --skip-bundle
project/app/config/database.yml
を修正してコンテナで立ち上げたMySQLのユーザ、パスワード情報を設定します。
default: &default
adapter: mysql2
encoding: utf8mb4
pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
username: root
password: pass
host: mysql
...
migrationファイルを作成して、ER図で出力するテーブルを作成していきます。
今回はSchemaSpyでER図を出力することが目的なので、ここでのカラム情報や型はよしなに作っていきます。
class CreateProducts < ActiveRecord::Migration[7.0]
def change
create_table :products do |t|
t.references :supplier, foreign_key: true, null: false
t.string :name
t.string :category
t.timestamps
end
end
end
class CreateSuppliers < ActiveRecord::Migration[7.0]
def change
create_table :suppliers do |t|
t.string :name
t.integer :phone_number
t.string :postal_code
t.string :address
t.timestamps
end
end
end
class CreateCustomers < ActiveRecord::Migration[7.0]
def change
create_table :customers do |t|
t.string :first_name
t.string :last_name
t.string :email
t.integer :phone_number
t.string :postal_code
t.string :address
t.timestamps
end
end
end
class CreateOrders < ActiveRecord::Migration[7.0]
def change
create_table :orders do |t|
t.references :customer, foreign_key: true, null: false
t.string :order_date
t.string :preferred_delivery_date
t.string :channel
t.string :address
t.integer :total_amount
t.timestamps
end
end
end
class CreateOrderDetails < ActiveRecord::Migration[7.0]
def change
create_table :order_details do |t|
t.references :product, foreign_key: true, null: false
t.references :order, foreign_key: true, null: false
t.integer :quantity
t.integer :price
t.timestamps
end
end
end
マイグレーションファイルの準備ができたら、コマンドを実行してテーブルを作成していきます。
docker-compose run web rails db:create
SchemaSpyの設定
検証用アプリの準備ができたので、次はSchemaSpyの設定です。project/schemaspy
のディレクトリを作り、DockerFile
とschemaspy.properties
を作成していきます。
FROM --platform=linux/amd64 schemaspy/schemaspy:snapshot
ENV TZ=Asia/Tokyo
USER root
COPY schemaspy.properties ./schemaspy
検証用アプリで使用している設定値を記載していきます。
schemaspy.t=mysql
schemaspy.dp=/drivers
schemaspy.host=mysql
schemaspy.port=3306
schemaspy.db=app_development
schemaspy.s=app_development
schemaspy.u=root
schemaspy.p=pass
project/docker-compose.yaml
にschemaspy
を追加して、使用するdocker image、自動生成されるファイルの出力先、schemaspy.properties
のパスなどを定義していきます。
schemaspy:
container_name: schemaspy
image: schemaspy/schemaspy:snapshot
volumes:
- ./schemaspy/schemaspy.properties:/schemaspy.properties
- ./schemaspy/output:/output
depends_on:
- mysql
environment:
SCHEMASPY_OUTPUT: /output
ここまで準備ができたらあとはコマンド実行するだけです!
いざ起動!!!
docker-compose up
/schemaspy/output
に出力されたindex.html
をブラウザでOpenするとテーブルの概要ページを確認することができます。 カラフルでいい感じですね!
テーブルを選択すると、そのカラムの詳細情報や関連のあるテーブルたちを確認できます。試しにproducts
テーブルを選択してみるとこんな感じです。右上のアイコンから、CSV、Excel、PDF形式でテーブルをExportできるのも色々便利そうです。
開発が進んでテーブル数が多くなってきた場合、全体のリレーションを表示すると情報量が多すぎて視認性が下がりそうなので、選択したテーブルが関係するリレーションのみを見れるのも便利ですね。
トップ画面でRelationships
項目を選択すると、データベース内に存在するすべてのテーブルのリレーションも閲覧できます。
ちょっと詰まったところ
基本的には簡単にER図を出力することができたのですが、SchemaSpyの出力時に発生したエラー紹介です。
ERROR - Bad config
Schema (-s/-schemas) was not provided and unable to deduce schema, schema is sometimes referred to as user/owner/database
sechemaspy.properties
でスキーマ名を指定していなかったことが原因だったので、以下の1行を追加して解消。
schemaspy.s=app_development
おわりに
開発初期にドキュメントを作成したけれど、日が経つにつれて最新版に更新されずにそのままになっている。。というのは陥りがちな光景だと思います。今回は、手元でSchemaSpyを実行してER図を自動生成する方法を試しましたが、Github Actions + S3 を使って、データベースに変更が加わったら最新のER図が自動生成される仕組みも、今後試してみたいなと思います。