2022年4月2日 星期六

在命令列上從 *.sql 檔直接產生 ER Diagram

拿到一個資料庫實例 (database instance) 第一件事就是畫出它的 ER Diagram。 例如 要下 join 指令時,我一定要看著 ER Diagram 才會下。 有很多 資料庫圖形介面的軟體 (例如 DBeaver) 都可以幫一個運行中的資料庫畫 ER Diagram。 可是其實單單是 DDL (就是 create table 之類的指令) 就應該已經提供足夠的資訊可以畫圖了啊... 我可不可以連 mysql 都不要安裝, 直接拿一個定義 schema 的 *.sql 檔, 用簡單的命令列工具就畫出 ER Diagram 呢? 在 github 上面找到兩個幾乎符合我需求的專案。

第一個是由 ehne 採用 python 所撰寫的 erdot。 它讀入一個 *.json 檔並產生一個 *.dot 檔。 後者可以再餵給 graphviz 以便產生 svg/jpg/png 等等各種格式的圖檔。 安裝很簡單: pip3 install ERDot 。 執行檔放在 $HOME/.local/bin 。 如果在 echo $PATH 指令的輸出裡面沒看到這個路徑, 那就需要在 ~/.bashrc 最後面加上一句 export PATH=$PATH:$HOME/.local/bin 。 必須開啟新的終端機線分頁才會生效。

第二個是由 Andrew Gallant (BurntSushi) 採用 haskell 所撰寫的 erd。 輸入資料是名為 *.er 的簡單文字格式檔案。 它可以直接產生各種格式的圖檔, 或者也可以產生 *.dot 。 我在 linux mint 20.2 上面這樣安裝:

sudo apt install -y haskell-stack
stack upgrade
wget https://github.com/BurntSushi/erd/archive/refs/heads/master.zip -O erd-master.zip
unzip erd-master.zip
cd erd-master/
stack install

注意: (1) 安裝過程使用超過 3.5G 的空間, 撐爆我的虛擬機! 只好回到實體機器, 才順利安裝成功。 (2) 如果沒有做 stack upgrade 這一步, 可能會遇到 404 not found 之類的錯誤。 做這一步時會被要求 sudo 權限以便安裝執行檔。

於是我寫了 兩個小程式 合起來就可以把一個定義 schema 的 *.sql 檔轉成上述兩者認得的輸入格式。 Php 語言實在不是我的菜, 但是為了呼叫 Cal Henderson 所寫的 SQLParser, 第一個程式只好用 php 撰寫。 請把 pmysql.php 下載到一個空的目錄, 並且在那個目錄執行 composer require iamcal/sql-parser 以便安裝所有的相依套件。 再把 json2erd.py 下載到 ~/.local/bin/ 並且執行 chmod a+x ~/.local/bin/json2erd.py 。 下圖是 ER Diagram 繪圖工作流程:

ER Diagram 繪圖工作流程

現在可以下載 sakila 範例資料庫, 然後執行 php pmysql.php /path-to/sakila-schema.sql | json2erd.py -t busu | erd -f svg > sakila-busu.svg 就會產生 svg 格式的 ER Diagram。 至於 ehne 的 erdot, 因為它不支援 pipe, 所以要分三個步驟來產生 svg 圖檔:

php pmysql.php /path/to/sakila-schema.sql | json2erd.py -t ehne > sakila-ehne.json
erdot sakila-ehne.json
dot -Tsvg sakila-ehne.dot > sakila-ehne.svg

另一個範例是 學校行政資料庫。 在定義 schema 的 *.sql 檔裡面, 表格名稱之前的資料庫名稱要先刪掉, 才可以餵給 pmysql.php, 因為 SQLParser 不認得這種語法:

wget https://raw.githubusercontent.com/travisrecupero/School-Database-in-mySQL/master/School%20Database.sql
perl -pe 's/`Final`\.//g' School\ Database.sql > ~/school.sql
php pmysql.php ~/school.sql | json2erd.py -t busu | erd -f svg > school-busu.svg

以下是最終產生的 ER Diagram。

sakila 的 ER Diagram, busu 版 sakila 的 ER Diagram, ehne 版 school 的 ER Diagram, busu 版 school 的 ER Diagram, ehne 版

本文有 英文版

沒有留言:

張貼留言

因為垃圾留言太多,現在改為審核後才發佈,請耐心等候一兩天。