LoginSignup
13
0

More than 1 year has passed since last update.

RailsアプリにSchemaSpyを導入してER図を自動生成してみた(MySQL 8.0)

Last updated at Posted at 2022-12-22

はじめに

メタップスアドベントカレンダー第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アプリを作成していきます。
プロジェクト配下にDockerFiledocker-compose.ymlを作成します。

project/DockerFile
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"]
project/docker-compose.yml
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

DockerFiledocker-compose.ymlの準備ができたらrails newコマンドを実行してアプリを作成します。

docker-compose run --no-deps web rails new . --force --database=mysql --skip-bundle

project/app/config/database.ymlを修正してコンテナで立ち上げたMySQLのユーザ、パスワード情報を設定します。

database.yml
default: &default
  adapter: mysql2
  encoding: utf8mb4
  pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
  username: root
  password: pass
  host: mysql

...

migrationファイルを作成して、ER図で出力するテーブルを作成していきます。
今回はSchemaSpyでER図を出力することが目的なので、ここでのカラム情報や型はよしなに作っていきます。

20221205093018_create_products.rb
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
20221205002147_create_suppliers.rb
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
20221205100523_create_customers.rb
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
20221205100739_create_orders.rb
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
20221205100903_create_order_details.rb
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のディレクトリを作り、DockerFileschemaspy.propertiesを作成していきます。

schemaspy/DockerFile
FROM --platform=linux/amd64 schemaspy/schemaspy:snapshot

ENV TZ=Asia/Tokyo
USER root
COPY schemaspy.properties ./schemaspy

検証用アプリで使用している設定値を記載していきます。

schemaspy/schemaspy.properties
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.yamlschemaspyを追加して、使用するdocker image、自動生成されるファイルの出力先、schemaspy.propertiesのパスなどを定義していきます。

project/docker-compose.yml
  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

このようなログが出れば成功です!
スクリーンショット 2022-12-18 18.57.40.png

/schemaspy/output に出力されたindex.htmlをブラウザでOpenするとテーブルの概要ページを確認することができます。 カラフルでいい感じですね!
スクリーンショット 2022-12-18 19.21.34.png

テーブルを選択すると、そのカラムの詳細情報や関連のあるテーブルたちを確認できます。試しにproductsテーブルを選択してみるとこんな感じです。右上のアイコンから、CSV、Excel、PDF形式でテーブルをExportできるのも色々便利そうです。

スクリーンショット 2022-12-18 19.40.27.png

開発が進んでテーブル数が多くなってきた場合、全体のリレーションを表示すると情報量が多すぎて視認性が下がりそうなので、選択したテーブルが関係するリレーションのみを見れるのも便利ですね。

スクリーンショット 2022-12-18 19.45.29.png

トップ画面でRelationships項目を選択すると、データベース内に存在するすべてのテーブルのリレーションも閲覧できます。

スクリーンショット 2022-12-18 19.28.22.png

ちょっと詰まったところ

基本的には簡単に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図が自動生成される仕組みも、今後試してみたいなと思います。

13
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
13
0