Rails ERDも便利なのですが、テーブル単位のリレーションでカラム単位で見たいし、テーブル数が多くなると見難いので、SchemaSpyを試してみました。

やってみた解った事は、ERDではモデルを見てリレーションを判断しているが、SchemaSpyはDBのみなので、DBにforeign_keyがないとER図が出ない。
-railsオプションがありますが、あくまでもActive Recordのルールに従っている場合しか対応できません。

SchemaSpyの挙動

SchemaSpyはJavaで動いて、DBにJDBCドライバで接続できればOKなので、必要な時に手動で叩いても良いし、migrate時やCircleCI等で自動生成するでも良さそう。

前提

Javaがインストールされている

% java -version 
java version "1.8.0_281"
Java(TM) SE Runtime Environment (build 1.8.0_281-b09)
Java HotSpot(TM) 64-Bit Server VM (build 25.281-b09, mixed mode)

Graphvizがインストールされている(任意)

SchemaSpyに組み込まれているモジュールを使うオプションもあるので任意。

% dot -V
dot - graphviz version 2.47.0 (20210316.0004)

DBに接続できる環境から実行

今回は、前回作成したローカルのDockerに接続しました。
既存のRailsアプリにDockerを導入する

localhostだとポート番号を指定してもsocket接続になってしまう。

% mysql -h localhost -P 3306 -u root -p rails_app_development
Enter password: 
ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/tmp/mysql.sock' (2)

IP指定にすればOK

% mysql -h 127.0.0.1 -u root -p rails_app_development   
Enter password: 
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A

Welcome to the MariaDB monitor.  Commands end with ; or \g.
Your MySQL connection id is 19
Server version: 8.0.25 MySQL Community Server - GPL

Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

MySQL [rails_app_development]> \q
Bye

ちなみにPostgreSQLの場合

% psql -h localhost -u postgres -d rails_app_development   

SchemaSpyの環境作成

適当なディレクトリを作って、その中で

% wget https://github.com/schemaspy/schemaspy/releases/download/v6.1.0/schemaspy-6.1.0.jar

% mkdir jdbc
% cd jdbc

MySQLに接続する場合
% wget https://repo1.maven.org/maven2/mysql/mysql-connector-java/8.0.20/mysql-connector-java-8.0.20.jar

PostgreSQLに接続する場合
% wget https://jdbc.postgresql.org/download/postgresql-42.2.23.jar

cd ..
vi schemaspy.properties

MySQLに接続する場合の例

schemaspy.t=mysql
schemaspy.dp=jdbc
schemaspy.host=127.0.0.1
schemaspy.port=3306
schemaspy.s=rails_app_development
schemaspy.db=rails_app_development
schemaspy.u=root
schemaspy.p=xyz789
schemaspy.o=schemaspy

PostgreSQLに接続する場合の例

schemaspy.t=pgsql
schemaspy.dp=jdbc
schemaspy.host=127.0.0.1
schemaspy.port=5432
schemaspy.s=public
schemaspy.db=rails_app_development
schemaspy.u=postgres
schemaspy.p=xyz789
schemaspy.o=schemaspy

SchemaSpyを実行

Graphvizがインストールされている場合
% java -jar schemaspy-6.1.0.jar
Graphvizがインストールされていない場合
% java -jar schemaspy-6.1.0.jar -vizjs
  ____       _                          ____
 / ___|  ___| |__   ___ _ __ ___   __ _/ ___| _ __  _   _
 \___ \ / __| '_ \ / _ \ '_ ` _ \ / _` \___ \| '_ \| | | |
  ___) | (__| | | |  __/ | | | | | (_| |___) | |_) | |_| |
 |____/ \___|_| |_|\___|_| |_| |_|\__,_|____/| .__/ \__, |
                                             |_|    |___/

                                              6.1.0

SchemaSpy generates an HTML representation of a database schema's relationships.
SchemaSpy comes with ABSOLUTELY NO WARRANTY.
SchemaSpy is free software and can be redistributed under the conditions of LGPL version 3 or later.
http://www.gnu.org/licenses/

INFO  - Starting Main v6.1.0 on xxxx with PID xxxx (/Users/xxxx/workspace/schemaspy/schemaspy-6.1.0.jar started by xxxx in /Users/xxxx/workspace/schemaspy)
INFO  - The following profiles are active: default
INFO  - Found configuration file: schemaspy.properties
INFO  - Started Main in 2.28 seconds (JVM running for 3.117)
INFO  - Loaded configuration from schemaspy.properties
INFO  - Starting schema analysis
INFO  - Connected to MySQL - 8.0.25
INFO  - Gathering schema details
Gathering schema details.........(0sec)
Connecting relationships.........(0sec)
Writing/graphing summary.INFO  - Gathered schema details in 0 seconds
INFO  - Writing/graphing summary
INFO  - Graphviz rendered set to ''
........(6sec)
Writing/diagramming detailsINFO  - Completed summary in 6 seconds
INFO  - Writing/diagramming details
......(1sec)
Wrote relationship details of 6 tables/views to directory 'schemaspy' in 9 seconds.
View the results by opening schemaspy/index.html
INFO  - Wrote table details in 1 seconds
INFO  - Wrote relationship details of 6 tables/views to directory 'schemaspy' in 9 seconds.
INFO  - View the results by opening schemaspy/index.html

% open schemaspy/index.html

ER図が出ない
schemaspy/relationships.html

All Relationships
× Missed Relationships!
No relationships were detected in the schema.

孤立したテーブルに出る
schemaspy/orphans.html

ベターな方法:railsオプション指定

あくまでもActive Recordのルールに従っている場合しか対応できません。
例えば、「t.references :user」= user_id → usersテーブルのid ならOK

Graphvizがインストールされている場合
% java -jar schemaspy-6.1.0.jar -rails
Graphvizがインストールされていない場合
% java -jar schemaspy-6.1.0.jar -vizjs -rails

ベストな方法:foreign_keyを追加

db/migrate/ にforeign_keyを追加

-      t.references :user, type: :bigint
+      t.references :user, type: :bigint, foreign_key: true

db:migrateすると、db/schema.rbに下記が追加される。

  add_foreign_key "infomations", "users"

Active Recordのルールに従っていない場合は、add_foreign_keyでカラム名や主キーを明示すれば良さそう。
add_foreign_key | Railsドキュメント

その他

MySQLでもコメント出るので入れた方が便利。(昔は入らなかったような。。。)

      t.string :title, null: false, comment: 'タイトル'
      t.string :summary, comment: '概要'
      t.text   :body, comment: '本文'

schemaspy/tables/(テーブル名).html

その下にインデックス
更にその下に、このテーブルをメインにしたER図が出そうなので、これは使えそう!

追伸:Meta追加

テーブルのコメントはmetaで設定できます。
また、foreign_keyを追加できないけど、リレーションを出したい場合にも使える。
Configuration — SchemaSpy 6.0.0 documentation

schemaspy.properties に追加

schemaspy.meta=schemaspymeta.xml

schemaspymeta.xml を作成

<schemaMeta xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="http://schemaspy.org/xsd/6/schemameta.xsd" >
    <tables>
        <table name="users" comments="ユーザー" />
        <table name="admin_users" comments="管理者" />
        <table name="infomations" comments="お知らせ" />
    </tables>
</schemaMeta>

今回のコミット内容
SchemaSpyをSQLite3に使ってみる で一緒に追加しています。
https://dev.azure.com/nightonly/rails-app-origin/_git/rails-app-origin/commit/44c8267330ca6f3e562115a6063bb1925abb51da

SchemaSpyでER図とDB設計書を自動生成する” に対して3件のコメントがあります。

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です