はじめに
RDSのデータ構造を確認するためにER図を作成したい。開発中にテーブルが増えていくので、簡単に作りたい。ということで、調べたらSchemaSpyというツールがあり、比較的簡単に生成・出力できることを知ったので、使ってみました。いろいろな方のSchemaSpyの記事を参考にさせていただきましたが、環境差異等もあり、いろいろつまずいたところもあったので、備忘録として残しておきます。
参考
下記の記事を参考にさせていただきました。
- まだER図の管理で消耗してるの? SchemaSpy でER図を自動生成して管理する
- DockerでサクッとDBからER図を作成する
- DockerでサクッとDBからER図を作成する(MySQL 5.5.45+, 5.6.26+ and 5.7.6+)
SchemaSpyとは
DBに接続すると、DBのテーブルの定義内容を読み取って、素敵なUIのHTMLとして出力してくれるツールです。Java製のツールなのですが、Dockerイメージが公開されているので、導入が簡単です ♪
Dockerイメージ:https://hub.docker.com/r/schemaspy/schemaspy/
ER図の生成
それではやってみたいと思います。
構成図
EC2 OS : Amazon Linux 2
DBの種類 : MySQL 5.7.22
RDSの操作用に踏み台EC2をたてています。このEC2にsshで接続して、RDSのデータ構造をER図にします。そして、ローカルで、生成されたHTMLを開きます。
本記事では、SchemaSpyを用いてのER図生成箇所にフォーカスしています。
いざ生成
EC2にDockerのインストール
Dockerイメージを使ってSchemaSpyを使用するので、まずDockerのインストールから始めます。Dockerのインストールは「AWS EC2インスタンスにdockerとdocker-composeをインストールして簡単なWEBサービスを立ち上げる方法」を参考にさせていただきました。
$ sudo yum install -y docker
$ sudo service docker start
# ec2-userがdockerコマンドを実行できるように、ec2-userをdockerグループに入れる
$ sudo usermod -a -G docker ec2-user
一度ログアウトして再ログインする。
# インストール確認
$ sudo docker info
SchemaSpy Dockerイメージの取得
$ docker pull schemaspy/schemaspy
# インストール確認
$ docker images
REPOSITORYにschemaspy/schemaspy
が追加されていればOKです。
schema生成(失敗)
$ docker run -v "$PWD/schema:/output" --net="host" schemaspy/schemaspy:6.1.0 -t mysql -host <ホスト名>:<ポート> -db <DB名> -u <DBユーザ名> -p <DBパスワード> -connprops useSSL\\=false -s information_schema
上記のコマンドで生成を試みましたが、エラーが出てうまくいかなかったので、次のように対応しました。
対応策1 パスワードを別定義
パスワードをダブルクォーテーションでくくらず、直接生成コマンドに書いたのが、上手くいかなかった一番の原因でした。特殊文字/予約語が入っていたりすると別の意味になってしまい、思わぬところでエラーになってしまうことがわかりました。
なので、export
コマンドを使ってパスワードを環境変数に定義しました。
$ export DB_PASS="<DBパスワード>"
もしくは、生成コマンドに入れる際に、-p "<DBパスワード>"
とダブルクォーテーションでくくるのでも大丈夫でした。この場合は環境変数に入れる上記のフローは不要です。
対応策2 ディレクトリの作成
出力するために、下記のディレクトリを作成します。作成せずに生成すると、ERROR - IOException Unable to create directory /output/tables
というエラーが出てしまいます。おそらく権限の問題かなと思います。ただ、このディレクトリには出力されたファイルを保存するわけではありません。
$ mkdir -p schema/output/tables
オプション-p
を設定することで、schema
、output
、tables
のディレクトリを一度に作成することができます。
対応策3 schema生成
先ほどのschema生成(失敗)では、オプション-s
のあとにinformation_schema
を指定しましたが、RDSを作成した際に作ったマスターDBユーザだと権限が足りないようです。なので、ER図を生成したいDB名を再度指定するようにしました。
$ docker run -v "$PWD/schema:/output" --net="host" schemaspy/schemaspy:6.1.0 -t mysql -host <ホスト名>:<ポート> -db <DB名> -u <DBユーザ名> -p ${DB_PASS} -connprops useSSL\\=false -s <DB名>
先ほどexport
で外に出したパスワードは、${DB_PASS}
で読み込むことができます。
これでカレントディレクトリに作成していたschema
配下にファイルが作成されます。
ローカルにダウンロード
生成したファイルをローカルにダウンロードします。
# EC2内で実行
$ zip -r schema.zip schema
$ exit
# ローカルで実行
$ scp -i "$HOME/.ssh/<pemキー>" ec2-user@<IPアドレス>:/home/ec2-user/schema.zip ./
$ unzip schema.zip
ER図の閲覧
schema/index.html
を開くとDBの情報を見ることができます。素敵なUIです!
やっぱりローカルから生成したい
sshでEC2に接続して上記のコマンドを実行して、ローカルにコピーするのも、テーブルが増えるたびに実行するのは面倒なので、わたくし初めてシェルスクリプトを書いてみました!
2回目以降はDockerのインストールなどの準備は不要なので、そのあたりは省きます。
実装
#!/bin/bash
set -e
# Dockerの起動
sudo service docker start
# DBパスワードの入力
echo -n DB_PASS:
read DB_PASS
# schema生成
docker run -v "$PWD/schema:/output" --net="host" schemaspy/schemaspy:6.1.0 -t mysql -host <ホスト名>:<ポート> -db <DB名> -u <DBユーザ名> -p ${DB_PASS} -connprops useSSL\\=false -s <DB名>
# ファイルの圧縮
zip -r schema.zip schema
# Dockerの停止
sudo service docker stop
exit 0
上記のシェルスクリプトをEC2にコピーしておきます。
$ scp -i "$HOME/.ssh/<pemキー>" ec2.sh ec2-user@<パブリックIP>:/home/ec2-user/
ローカルには下記のシェルスクリプトを用意します。
#!/bin/bash
set -e
# EC2のパブリックDNS、もしくはパブリックIPの入力
echo -n TARGET_EC2:
read TARGET_EC2
# EC2でec2.shをたたく
ssh -i "$HOME/.ssh/<pemキー>" ec2-user@${TARGET_EC2} 'bash /home/ec2-user/ec2.sh'
# ローカルにコピー
scp -i "$HOME/.ssh/<pemキー>" ec2-user@${TARGET_EC2}:/home/ec2-user/schema.zip ./
unzip schema.zip
# index.htmlを開く
open ./schema/index.html
exit 0
実行
$ bash local.sh
上記のコマンドをたたくと、EC2のパブリックIPとDBのパスワードの入力を求められるので、その2つを順番に入力していくだけで、ローカルから生成できるようになりました!
めでたしめでたし!!
おわりに
SchemaSpyを使ってのER図の作成は、Dockerイメージの有り難さを感じつつ、簡単に作成することができました!
今後パスワードの書き方は気をつけます。
そして、初めてシェルスクリプトを書いてみました!
ssh接続からEC2内の操作まで書いたシェルスクリプトをローカルで実行すると、EC2にsshで接続でしたところでその後の操作が実行されず止まってしまいました。なので、ローカルで実行する部分とEC2内で実行する部分を分けることにしました。
上記のような操作だと、思ったより簡単に書くことができて、作業時間の短縮にもなるので、これからも活用していこうと思います!