MySQLからER図を描くとき、面倒臭いとか思ったりしたことはありませんか!!
そんなときにER図を描く手間を減らしてくれる、便利なツールDB2mermaidがあったので簡単に紹介します!
本日の主役
DB2mermaid · PyPI
環境
ツール名 | バージョン |
---|---|
MacBook Pro(M1 mac) | mac OS Monterey 12.2.1 |
DB2mermaid | 1.0.3 |
Python | 3.10.9 |
mysqlclient | 2.1.1 |
SQLAlchemy | 2.0.7 |
Docker | 20.10.11 |
Docker Compose | v2.2.1 |
MySQL(Docker Imageで代用) | 5.7 |
DBeaver Community Edition | 23.0.0.202303040621 |
フォルダ構成
最終的に下記のようになりました。
db2mermaid ├── docker │ ├── Dockerfile │ ├── docker-compose.yml │ └── mysql │ ├── 00-sakila-schema.sql │ ├── 10-sakila-data.sql │ └── sakila.mwb └── main.py
環境構築
DB2mermaidの公式を見るとRequireに
- Python3.10
- sqlalchemy
- mysqlclient
- your (mysql)DB
とあるため、これを参考に環境を作成していきます。
仮想環境の作成
condaで仮想環境を用意しました。
# conda create -n db2mermaid python=3.10 #仮想環境の作成 # conda activate db2mermaid # db2mermaidをactivate
必要なパッケージのインストール
必要なパッケージとしてsqlalchemyやmysqlclientが書かれていますが、パッケージが入っていなくてもおそらくDB2mermaidをインストールするときに勝手に最新版のパッケージを取得してくれるはずです。
# pip install DB2mermaid
私は下記の順番でインストールしました。
# pip install SQLAlchemy # pip install mysqlclient # pip install DB2mermaid
DockerでMySQLを起動
サンプルデータの取得
DockerでMySQLを起動しデータを投入していきます。 データですが、DB2mermaidの公式を見るとどうやらSakilaを使っているようですので、そちらを利用します。
https://downloads.mysql.com/docs/sakila-db.tar.gz
上記をダウンロードし、db2mermaid/docker/mysql配下にsakila-schema.sqlとsakila-data.sqlとsakila.mwbを配置します。
docker ├── Dockerfile ├── docker-compose.yml └── mysql ├── 00-sakila-schema.sql ├── 10-sakila-data.sql └── sakila.mwb
このとき、ファイル名は00-sakila-schema.sql、10-sakila-data.sqlに変えておきましょう。
Dokerfileの作成
dockerディレクトリ配下に、Dockerfileを作成します。
FROM --platform=linux/x86_64 mysql:5.7 COPY ./mysql/*.sql /docker-entrypoint-initdb.d/
FROM部分に--platform=linux/x86_64
が入っていますが、M1Macで必要な記載になります。
WindowやIntel Mac系は要らないはずです。
下記記事が参考になるかもしれません。
M1Mac環境でDockerのMySQLを動かす - Qiita
docker-compose.ymlの作成
dockerディレクトリ配下に、docker-compose.ymlを作成します。
version: '3' services: mysql: container_name: mysql_container build: context: . dockerfile: Dockerfile ports: - 3306:3306 environment: MYSQL_ROOT_PASSWORD: password MYSQL_DATABASE: sakila MYSQL_USER: user MYSQL_PASSWORD: password TZ: "Asia/Tokyo" restart: always
ここまでくると、下記のようなディレクトリ構成になっているはずです。
docker ├── Dockerfile ├── docker-compose.yml └── mysql ├── 00-sakila-schema.sql ├── 10-sakila-data.sql └── sakila.mwb
MySQLを起動
dockerディレクトリ配下で、下記コマンドを実行します。 実行後は特にエラーが起きなければ、正常に起動できているはずです。
# docker compose up -d --build # docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES d2c54b60b1ac docker_mysql "docker-entrypoint.s…" 2 seconds ago Up 2 seconds 0.0.0.0:3306->3306/tcp, 33060/tcp mysql_container
DBeaverで接続確認
DBeaverを利用して実際にMySQLに接続できるか確認してみましょう。
DBeaverについて簡単に説明すると、マルチプラットフォームデータベースツールで、MySQLだけでなく、PostgreSQL、Sql Server、MariaDBなど様々なデータベースをサポートしています。
詳しい使い方などは、公式などを参考にしてください。
接続方法は下記の通りです。
① DBeaverを開く
② 接続を選択
③ MySQLを選択
色々ありますが、今回はMySQL(左上)を選択します。
④ 下記のように設定
Server host:127.0.0.1
port:3306
Databases::sakila
ユーザー名:root
パスワード:passowrd
パスワードですが、ユーザ名がroot
になっているため、docker-compose.yml
で指定したMYSQL_ROOT_PASSWORD
のpassword
を入れます。
⑤ テスト接続
テスト接続を押下し、接続が確認できればOK
実際にSQLを叩いてみると接続できていることがわかります。
DB2mermaidを利用する
DB2mermaidを利用して、先ほどのMySQLのER図を作成してみましょう。
Pythonファイルの作成
DB2mermaidに記載のある通りに書けば動きますので、その通りにコードを書いていきます。
db2mermaidディレクトリ配下にmain.pyを作成します。
公式に書いてあるuserやdb_nameは適切なものに書き換えます。
# coding:utf-8 from db2mermaid.db2mermaid import DB2Mermaid if __name__ == '__main__': dm = DB2Mermaid() dm.init_db("root", "password", "127.0.0.1", "3306", "sakila") dm.generate()
ここまでくると、下記のようなディレクトリ構成になっているかと思います。
db2mermaid ├── docker │ ├── Dockerfile │ ├── docker-compose.yml │ └── mysql │ ├── 00-sakila-schema.sql │ ├── 10-sakila-data.sql │ └── sakila.mwb └── main.py
実行してER図を取得する
main.py
を実行します。
# python main.py db_url: mysql://root:password@127.0.0.1:3306/sakila SAWarning: Did not recognize type 'geometry' of column 'location' self.meta.reflect(bind=engine) table name🌟 actor table name🌟 address table name🌟 city table name🌟 country table name🌟 category table name🌟 customer table name🌟 store table name🌟 staff table name🌟 film table name🌟 language table name🌟 film_actor table name🌟 film_category table name🌟 film_text table name🌟 inventory table name🌟 payment table name🌟 rental
実行が終わると、db2mermaidディレクトリ配下に下記のようなer.mdファイルが作成されます。
```mermaid
erDiagram
actor{
SMALLINT actor_id PK
VARCHAR(45) first_name
VARCHAR(45) last_name
TIMESTAMP last_update
}
address{
SMALLINT address_id PK
VARCHAR(50) address
VARCHAR(50) address2
VARCHAR(20) district
SMALLINT city_id FK
VARCHAR(10) postal_code
VARCHAR(20) phone
NULL location
TIMESTAMP last_update
}
city{
SMALLINT city_id PK
VARCHAR(50) city
SMALLINT country_id FK
TIMESTAMP last_update
}
country{
SMALLINT country_id PK
VARCHAR(50) country
TIMESTAMP last_update
}
category{
TINYINT category_id PK
VARCHAR(25) name
TIMESTAMP last_update
}
customer{
SMALLINT customer_id PK
TINYINT store_id FK
VARCHAR(45) first_name
VARCHAR(45) last_name
VARCHAR(50) email
SMALLINT address_id FK
TINYINT active
DATETIME create_date
TIMESTAMP last_update
}
store{
TINYINT store_id PK
TINYINT manager_staff_id FK
SMALLINT address_id FK
TIMESTAMP last_update
}
staff{
TINYINT staff_id PK
VARCHAR(45) first_name
VARCHAR(45) last_name
SMALLINT address_id FK
BLOB picture
VARCHAR(50) email
TINYINT store_id FK
TINYINT active
VARCHAR(16) username
VARCHAR(40) password
TIMESTAMP last_update
}
film{
SMALLINT film_id PK
VARCHAR(128) title
TEXT description
YEAR release_year
TINYINT language_id FK
TINYINT original_language_id FK
TINYINT rental_duration
DECIMAL(4_2) rental_rate
SMALLINT length
DECIMAL(5_2) replacement_cost
ENUM rating
SET special_features
TIMESTAMP last_update
}
language{
TINYINT language_id PK
CHAR(20) name
TIMESTAMP last_update
}
film_actor{
SMALLINT actor_id PK
SMALLINT film_id PK
TIMESTAMP last_update
}
film_category{
SMALLINT film_id PK
TINYINT category_id PK
TIMESTAMP last_update
}
film_text{
SMALLINT film_id PK
VARCHAR(255) title
TEXT description
}
inventory{
MEDIUMINT inventory_id PK
SMALLINT film_id FK
TINYINT store_id FK
TIMESTAMP last_update
}
payment{
SMALLINT payment_id PK
SMALLINT customer_id FK
TINYINT staff_id FK
INTEGER rental_id FK
DECIMAL(5_2) amount
DATETIME payment_date
TIMESTAMP last_update
}
rental{
INTEGER rental_id PK
DATETIME rental_date
MEDIUMINT inventory_id FK
SMALLINT customer_id FK
DATETIME return_date
TINYINT staff_id FK
TIMESTAMP last_update
}
```
作成されたER図を見る
作成されたer.mdからER図を可視化するには、オンラインエディタを使う場合とVScodeで見る方法など色々あります。
オンラインエディタの場合
オンラインエディタの場合、Mermaid Live Editorがあるので、そちらを利用します。
Online FlowChart & Diagrams Editor - Mermaid Live Editor
ただし、er.mdの中身をそのまま貼り付けるとエラーが出てしまいますので、er.mdファイルの上部にある```mermaid
と下部にある```
を削除して貼り付けましょう。
オンラインエディタ上では下記のようにしてみることが可能です。
VSCodeで見る場合
VSCodeで見る場合は、拡張機能でMarkdown Preview Mermaid Supportというものがあるので、それをインストールすればプレビュー機能(Macの場合:Cmd + k, v)から見ることが可能です。
まとめ
DB2mermaidを利用して、MySQLからER図を作成することができました。
ただ、今のところ対応しているのはMySQLのみで、また、テーブル間のリレーションも生成できないようです。
この辺りは将来的に対応してくれるのをゆっくり待ちましょう。( ̄∀ ̄)
その他:トラブルシューティングなど
mysqlclientインストール時のエラーについて
mysqlclientをインストールしようとすると、私の場合下記のエラーが出てきました。
Collecting mysqlclient Using cached mysqlclient-2.1.1.tar.gz (88 kB) Preparing metadata (setup.py) ... error error: subprocess-exited-with-error × python setup.py egg_info did not run successfully. │ exit code: 1 ╰─> [16 lines of output] /bin/sh: mysql_config: command not found /bin/sh: mariadb_config: command not found /bin/sh: mysql_config: command not found Traceback (most recent call last): File "<string>", line 2, in <module> File "<pip-setuptools-caller>", line 34, in <module> File "/private/var/folders/k7/x4m8rfmn2p1_xy7_24gdkvyc0000gn/T/pip-install-uc7mnp5y/mysqlclient_b7fe84c002c94e8ba150581772b02fdd/setup.py", line 15, in <module> metadata, options = get_config() File "/private/var/folders/k7/x4m8rfmn2p1_xy7_24gdkvyc0000gn/T/pip-install-uc7mnp5y/mysqlclient_b7fe84c002c94e8ba150581772b02fdd/setup_posix.py", line 70, in get_config libs = mysql_config("libs") File "/private/var/folders/k7/x4m8rfmn2p1_xy7_24gdkvyc0000gn/T/pip-install-uc7mnp5y/mysqlclient_b7fe84c002c94e8ba150581772b02fdd/setup_posix.py", line 31, in mysql_config raise OSError("{} not found".format(_mysql_config_path)) OSError: mysql_config not found mysql_config --version mariadb_config --version mysql_config --libs [end of output] note: This error originates from a subprocess, and is likely not a problem with pip. error: metadata-generation-failed × Encountered error while generating package metadata. ╰─> See above for output. note: This is an issue with the package mentioned above, not pip. hint: See above for details.
上記の中にOSError: mysql_config not found
を見つけました。どうやらmysql_configがないらしい。
実際に探してみてもありませんでした。
# which mysql_config mysql_config not found
そんなこんなで探していると下記記事が見つかりまして。
mysql_config not foundとでたときの対処法 - Qiita
こちらの記事に書いてあることを順に上からやっていきます。
# brew install mysql-connector-c # echo 'export PATH="/opt/homebrew/opt/mysql-client/bin:$PATH"' >> ~/.zshrc # export PATH="/opt/homebrew/opt/mysql-client/bin:$PATH" # which mysql_config /opt/homebrew/opt/mysql-client/bin/mysql_config # chmod 777 /opt/homebrew/opt/mysql-client/bin/mysql_config
で、最後にvi
でmysql_configファイルを開いて編集するらしいのですが、私の場合は下記のようになっていたため、編集しなくてもいいと思い、今回は無視しました。
# vi /opt/homebrew/opt/mysql-client/bin/mysql_config ~省略~ libs="-L$pkglibdir" libs="$libs -lmysqlclient -lz -L/opt/homebrew/lib -lzstd -L/opt/homebrew/opt/openssl@1.1/lib -lssl -lcrypto -lresolv" ~省略~
再度pip install mysqlclient
することで無事installすることができました。
ファイル名を変える意味
サンプルデータの取得部分でファイル名を、00-sakila-schema.sql、10-sakila-data.sqlに変更した意味ですが、Dockerが関係しています。
DockerのSQL系のイメージは、コンテナ内の特定の場所にファイルを配置すると、ファイル名を元に自動的にデータベースを作成してくれます。
このときの実行順ですが、Dockerではファイル名順に実行します。
つまり、sakila-schema.sqlとsakila-data.sqlのままだと、sakila-data.sqlが先に実行され、sakila-schema.sqlが後から実行されることになり、テーブルなどの定義がないままデータを投入しようとしてDBの作成に失敗してしまいます。
sakila-data.sql # 1番目に実行 sakila-schema.sql # 2番目に実行
これを避けるため、ファイル名を00-sakila-schema.sql、10-sakila-data.sqlに変えたのでした。
MySQL系に限った話ではないですが、実行順には気をつけるようにしましょう。
参考記事
mysql_config not foundとでたときの対処法 - Qiita
M1Mac環境でDockerのMySQLを動かす - Qiita