erdscope #
erdscope は、稼働中の MySQL または PostgreSQL データベースから自己完結型のインタラクティブな ER 図と、
必要に応じてExcel テーブル定義書を生成します。単一の Python ファイル
(erd.py、インストール不要)として配布され、必須の依存関係はゼロです。
データベースが唯一の真実源です — テーブル、カラム、コメント、インデックス、実際の外部キーはすべて
データベースのカタログ(MySQL では information_schema、PostgreSQL では
pg_catalog)から取得されます。アプリケーションコード(Rails、Prisma、Django)を
--models で任意に重ね合わせることで、データベース単体では表現できない関連のセマンティクス
(has_many :through、ポリモーフィック関連など)を追加できます。
ライブデモを試す → — コメント・インデックス・実際の FK・推測された関連を含む小さな EC サイトのスキーマです。 デモの内容はすべて単一の自己完結型 HTML ファイルであり、あなた自身の図も同じ方法で生成されます。
データベースの真実
テーブル、カラム(完全な SQL 型、デフォルト値、extra 属性)、コメント、インデックス、実際の FK 制約 — すべてデータベースから直接読み取ります。
コード側のセマンティクスを重ね合わせ
--models は Rails / Prisma / Django の関連をマージします。association ですでにカバーされている DB FK は重複排除され、残りには「DB FK」バッジが付きます。
インタラクティブな探索
深度と方向を指定したフォーカス、2段階の非表示、テーブル・カラム検索、名前付きビュー、共有リンク。
読みやすいレイアウト
ビューポートを考慮した自動配置、ドラッグ時のスナップ、複数選択での整列/分布、Auto-tidy、undo/redo。
エクスポート
PNG、SVG、Mermaid、PlantUML — それぞれコピーとダウンロードに対応 — に加えて Excel ワークブック。
論理名
テーブルの DB コメントは検索可能な「論理名」を兼ね、物理名と並べて表示されます。
インストール・必要要件 #
PyPI からインストールすると erdscope コマンドが使えるようになります。
pip install erdscope # または: pipx install erdscope
erdscope mysql://readonly@127.0.0.1:3306/myapp -o erd.html
何もインストールしたくない場合は、erd.py
が依存ゼロの単一ファイルなので、ダウンロードして任意の Python 3.9 以降で実行できます。このマニュアル全体で
使っている erdscope コマンドと完全に同じ動作です。
curl -O https://raw.githubusercontent.com/orapli/erdscope/main/erd.py
python3 erd.py mysql://readonly@127.0.0.1:3306/myapp -o erd.html
必要要件は厳密には Python 3.9 以降のみです。ツールをより使いやすくする2つのライブラリが
ありますが、どちらも完全にオプションです — インストールされていなくても erdscope は正しくフォールバック
して動作します。pip でインストールした場合は extras でまとめて導入できます
(pip install 'erdscope[mysql]' で PyMySQL、'erdscope[postgres]' で psycopg、
'erdscope[yaml]' で PyYAML、'erdscope[all]' で全部)。
| ライブラリ | 用途 | 未インストールの場合 |
|---|---|---|
| PyMySQL | MySQL 接続 | mysql CLI(PATH 上にある必要あり)へのシェルアウトにフォールバック — トラブルシューティング参照 |
| psycopg(または psycopg2) | PostgreSQL 接続 | psql CLI(PATH 上にある必要あり)へのシェルアウトにフォールバック — トラブルシューティング参照 |
| PyYAML | .yml/.yaml 設定ファイルの読み込み | .json 設定ファイルであれば依存関係なしで動作します。PyYAML がない状態で .yml/.yaml を指定した場合は、明確なエラーで終了します |
--excel 出力には上記のどれも不要です — スプレッドシート用パッケージではなく、
Python 標準ライブラリの zipfile/XML 処理を使って直接書き出しています。
もう2つのライブラリはテストスイート専用で、実行時には一切使われません:
openpyxl(ユニットテストで --excel 出力をラウンドトリップ検証)と
Playwright(ブラウザ E2E スイートで生成 HTML を操作)です。
どちらも図の生成・閲覧には不要です。
クイックスタート #
erdscope mysql://readonly@127.0.0.1:3306/myapp_production -o erd.html
# アプリケーションコードから解析した関連セマンティクスで拡張(任意)
erdscope mysql://readonly@127.0.0.1:3306/myapp_production \
--models /path/to/rails/app -o erd.html
# テーブル定義書も同時に出力
erdscope mysql://readonly@127.0.0.1:3306/myapp_production \
--excel table_definitions.xlsx -o erd.html
# PostgreSQL の場合も同じ — スキーマはデフォルトで public、?schema=name で上書き可能
erdscope postgres://readonly@127.0.0.1:5432/myapp_production -o erd.html
生成された erd.html を任意のブラウザで開いてください — すべてが1ファイルに内包されている
ので、メールで送ったり、Wiki にコミットしたり、共有ドライブに置いたりできます。
パスワードの扱い
読み取り専用の DB アカウントを使い、接続 URL にパスワードを書かないでください — シェル履歴に残ってしまいます。erdscope は次の順序でパスワードを解決します。
- URL に埋め込まれたパスワード(
mysql://user:pass@host/db)— 実運用では避けてください。 MYSQL_PWD(MySQL)/PGPASSWORD(PostgreSQL)環境変数(設定されている場合)。- それ以外で、標準入力が対話的な端末であれば、隠し入力のパスワードプロンプト
(
argvにもシェル履歴にも残りません)。
user:@host/db(明示的な空パスワード)と書いた場合も「パスワードが指定された」扱いになり、
プロンプトはスキップされます。PostgreSQL の場合、プロンプトに空行で答えると PGPASSWORD は
未設定のままになるため、libpq 自身の ~/.pgpass 参照がそのまま働きます。踏み台サーバー / SSH トンネル経由
ssh -N -L 3307:db-host:3306 bastion &
erdscope mysql://readonly@127.0.0.1:3307/myapp_production -o erd.html
CLIリファレンス #
この表は erd.py の argparse 定義に基づいて検証済みです — 手元のバージョンと
一致しているか、いつでも erdscope --help を実行して確認できます。
erdscope [mysql://user@host/db | postgres://user@host/db] [options]
| 引数 | 説明 |
|---|---|
mysql://… または postgres://… | 位置引数。データベース接続 URL。postgres:// は任意の ?schema=name(デフォルト public)を受け付けます。postgresql:// という表記も使えます。設定ファイルの engine/host/port/user/database から組み立てることもできます(パスワード用のフィールドはありません — 設定ファイル参照)。 |
-o, --output OUTPUT | 出力 HTML ファイル(デフォルト: erd.html) |
--models PATH | アプリケーションコードから解析した関連セマンティクスをマージ: Rails プロジェクト(または app/models ディレクトリ)、schema.prisma、または Django プロジェクト — ソースは自動判別されます |
--excel FILE.xlsx | テーブル定義書も出力: 概要シート+テーブルごとのシート |
--excel-template FILE.xlsx | ワークブックの色/フォント/罫線をテンプレート .xlsx から上書き — 5セル契約についてはエクスポートを参照。--excel なしでは効果がなく(警告が出ます) |
--max-rows N | テーブルごとにスクロールなしで表示するカラム数の上限(デフォルト: 15) |
--only 'user*,post*' | 指定した glob パターンに一致するテーブルのみを含める。繰り返し指定可、カンマ区切りリストも可 |
--exclude '*_logs' | 指定した glob パターンに一致するテーブルを除外。--only と同じ構文 |
--infer-fk | 実際の association/FK による裏付けがない場合に、*_id というカラム名から関連を推測する。デフォルトはオフ — トラブルシューティング参照 |
--table-map 'Widget=crm_widgets' | Rails 専用: 静的解析でテーブルを特定できないモデルのテーブルを上書き。繰り返し指定可、カンマ区切りリストも可 — トラブルシューティング参照 |
--config PATH | 設定ファイルからデフォルト値を読み込む。指定がない場合はカレントディレクトリの .erdscope.json/.yml/.yaml が自動検出されます |
--no-config | カレントディレクトリに .erdscope.* があっても自動検出をスキップする |
設定ファイル #
フラグの一覧が長くなってきたら、代わりに設定ファイルにまとめましょう。ツールを実行する場所に
.erdscope.json(PyYAML がインストールされていれば .erdscope.yml/.yamlも可)
を置くと自動的に読み込まれます — --config は不要です。ほとんどのキーは上記の CLI オプション
に対応します(snake_case)。engine/host/port/user/database
(DB 接続情報 — engine はデフォルトの "mysql" か "postgres" を指定し、
"postgres" にするとデフォルトポートも 5432 に切り替わります)と relations
(手動 FK 宣言)は設定ファイル専用で、対応する CLI オプションはありません。
{
"host": "127.0.0.1",
"port": 3306,
"user": "readonly",
"database": "myapp_production",
"output": "erd.html",
"models": "../myapp",
"max_rows": 15,
"infer_fk": true,
"only": ["user*", "post*"],
"table_map": { "Widget": "crm_widgets" },
"relations": [
{ "table": "orders", "column": "buyer_code", "references": "users" },
{ "table": "profiles", "column": "person_ref", "references": "users",
"one_to_one": true, "name": "owner" }
]
}
明示的な CLI フラグは常に同名の設定キーより優先され、値を完全に置き換えます(only のような
リスト値も設定ファイルの内容とマージされることはありません)。意図的に password/url
キーは存在しません — host/port/user/database が
別々のフィールドになっているのは、パスワードを書き込める場所をそもそも作らないためです。CLI と同じように
MYSQL_PWD/PGPASSWORD、~/.my.cnf/~/.pgpass、または
対話プロンプトで指定してください。
すべてのキーを説明した完全な注釈付きサンプルは
erdscope.example.yml
(ライブデモのスキーマがベース)を参照してください。
手動での関連宣言
relations は、他のどのソース(実際の FK 制約、*_id による名前推測、
--models によるコード解析)でも見つけられない関連を宣言します — 命名が特殊なカラムや、
gem 提供の concern・動的な association によって静的解析から隠れているものなどです。
--models をまったく使わなくても単独で機能し、設定ファイルだけで完全な関連グラフを
組み立てることもできます。優先順位はコード解析による association と同じです — --infer-fk
より先に適用される(そのため該当カラムに対する誤った名前ベースの推測も抑制します)ほか、同じカラムに
対する実際の DB FK 制約よりも優先されます。relations 内の未知のテーブル/カラム/参照先は
常にタイプミスとみなされ、サイレントに無視されるのではなく、必ずハードエラーになります。
only/exclude は
単なる文字列ではなく文字列のリストである必要があります(文字列のままだと1パターンとしてではなく
文字単位でマッチしてしまいます)。infer_fk は文字列の "true"/"false"
ではなく、真の JSON boolean である必要があります。型が一致しない場合、以前は図がサイレントに間違った
ものになっていましたが、現在は明確なエラーとして事前に検出されます — エラーに遭遇したら、上の例と
照らし合わせて値の型を確認してください。ビューアガイド #
以下はすべて、生成された HTML ファイル自体 — つまりブラウザで開く図そのもの — について説明しています。 CLI については触れません。読みながらライブデモで 実際に各コントロールを試してみてください。
ペイン #
ページは3つのペインで構成されています: Tables(左 — チェックボックス付きの テーブル一覧と検索)、diagram(中央の図)、Details(右 — 選択中の対象のカラム・インデックス・関連)です。
- リサイズ — サイドペインと図の間にある細い区切り線をドラッグします(幅は140px〜560pxの範囲に制限されます)。
- 折りたたみ / 展開 — ペインのタイトルバーにある ◀/▶ ボタンで折りたたみ、その端に現れる小さなタブから再表示できます。
- ペイン幅と折りたたみ状態は、次にこの図を開いたときのためにブラウザに記憶されます。
フォーカスと探索 #
テーブル(一覧上でもキャンバス上でも可)をダブルクリックするとそのテーブルに フォーカスします — 図はそのテーブルと関連テーブルだけに絞り込まれます。フォーカス中のテーブルを再度 ダブルクリックするか、Esc を押すか、✕ Back to overview / Exit focus ボタンのいずれかで全体表示に戻ります。
フォーカス中は上部のバーに 🔍 Focused: <テーブル名> (depth <深度>, <方向>)
と表示されます。左ペインのチェックボックスは全体表示にのみ影響し、フォーカス中のビューには影響しません
(その旨のヒントも表示されます)。Apply to checks は、フォーカスビューに
現在表示されているテーブルをそのまま全体表示側のチェック状態に反映してから、フォーカスを終了します。
フォーカス(および後述の Auto-expand)が何を引き込むかは、次の3つのコントロールで決まります。
| コントロール | 選択肢 | 効果 |
|---|---|---|
| Depth(深度) | 1 / 2 / 3 / ∞ | フォーカス中のテーブルから何ホップ先の関連まで含めるか |
| Direction(方向) | Both / Deps / Dependents | Deps はこのテーブルが依存しているもの(FK で参照している親)をたどります。Dependents はこのテーブルに依存しているもの(このテーブルを参照している子)をたどります。Auto-expand の設定に関わらず、各テーブルの ⊕ ボタンにもこの設定が適用されます。 |
| Auto-expand(自動展開) | ツールバーのチェックボックス | オンにすると、全体表示でチェックされているすべてのテーブルが起点となり、現在の深度/方向の範囲でその関連テーブルを引き込みます。フォーカスモードでは、この設定に関わらず常にフォーカス中のテーブルから展開します。 |
各ノードには ⊕ ボタンもあり、そのテーブルの直接の関連テーブルだけを(現在の方向設定に
従って)一時的に引き込みます — それ自体が新たな展開の起点になることはないため、1回のクリックでスキーマ
全体が芋づる式に広がることはありません。
orders にフォーカス — depth 2、Deps 方向。フォーカスバーに両方の設定が表示されています。ツールバーの depth/direction コントロールは、フォーカス中か Auto-expand がオンのときだけ表示されます。
テーブルの非表示 — 2段階 #
erdscope にはテーブルを表示から外す独立した2つの方法があり、強さが異なります。
| Exclude(除外) | Ban(禁止/完全非表示) | |
|---|---|---|
| トリガー | 一覧のチェックを外す、またはノードの ⊖ ボタン | 一覧の行にある 🚫 ボタンのみ |
| 強さ | 軽い — Auto-expand によって他のテーブルの関連先として再び現れたり、チェックを入れ直したり、他のテーブルの ⊕ から戻ってくることがあります | 強い — 禁止解除するまで、Auto-expand であっても二度と表示されません |
| 元に戻す | チェックを入れ直す | その行で再度 🚫、または何か禁止されている間だけ表示される赤いバナー内の Unban all |
フォーカス中のテーブルを禁止するとフォーカスは終了します。除外セットと禁止セットはどちらもブラウザに 記憶され、名前付きビューや共有リンクにも含まれます。
一覧の 🚫 ボタンで products を禁止した状態 — 取り消し線が引かれ、チェックボックスはロックされ、上の赤いバナーにカウントされます。
検索とハイライト #
erdscope には性質の異なる2つの検索ボックスがあります。
フィルタ(左ペイン、"Search tables / columns…")
テーブル名・カラム名・カラムのコメント・テーブルのコメントに一致します。入力するたびにテーブル一覧をその場でフィルタします。Enter を押すと図の中の最有力候補にジャンプし(表示から外れていれば戻し)、一致したカラムをハイライトします。
ハイライト(ツールバー、"Highlight…")
一致対象はフィルタと同じですが、表示からは何も取り除きません — 一致したテーブル/カラムに印を付け、それ以外を薄暗くするだけの、あくまでオーバーレイです。Enter/Shift+Enter で次/前の一致に移動します。選択状態と違い、ハイライトの検索語は PNG/SVG エクスポートにも引き継がれます。
どちらのボックスも、独立した Aa(大文字小文字を区別)と .*(正規表現)の
切り替えボタンを持っています — フィルタ側で正規表現モードを有効にしても、ハイライト側には影響しません。
user をハイライト — 一致したテーブル/カラムにアンバー色の枠が付き、それ以外は薄暗くなりますが、図から取り除かれるものは何もありません。
レイアウトと選択 #
- パン — 何もないキャンバス上をドラッグするか、2本指でスクロールします。
- ズーム — ピンチ操作 / Ctrl+スクロール、またはツールバーの
+/−/1:1/⊡ Fitボタン。 - 複数選択 — クリックで1つだけ選択、Shift-クリックまたは Ctrl/Cmd-クリックで選択に追加/削除、何もないキャンバス上から Shift-ドラッグでラバーバンド選択。何もないキャンバスをクリックするとすべて選択解除されます。
- ドラッグで移動 — 選択中のテーブルをドラッグすると、選択中のもの全体が一緒に動きます。ドラッグ中の端は近くのテーブルの端/中心に数ピクセル以内でスナップし、赤いガイド線(Figma のような)が表示されます — ドラッグ中に Alt を押すとスナップを無効化できます。
- 整列 / 分布 — 2つ以上選択すると、右ペインに ⇤ Left / ⇡ Top / ↔ Center / ↕ Middle が表示されます。3つ以上選択すると ⇔ Horiz. / ⇕ Vert. の分布も使えるようになります(両端のテーブルは固定したまま、間の間隔を均等にします)。
- Auto-tidy — 表示中のテーブル集合が変わるたびに、レイアウトを自動的に再配置・再フィットするツールバーのトグルです。
↺ボタンは Auto-tidy の設定に関わらず、その場で即座に再配置します。 - Undo/redo — ツールバーの
↶/↷ボタン、または Ctrl/Cmd+Z / Ctrl/Cmd+Shift+Z(もしくは Ctrl/Cmd+Y)。対象はテーブルの位置変更のみです。フォーカスの開始/終了や保存済みビューの読み込みはレイアウト全体を置き換えるため、その際に履歴はクリアされます。
3テーブルを選択した状態 — 3つ以上選択すると、Align(整列)とDistribute(分布)の両方が使えるようになります(2つの選択では Align のみ有効)。
カラム表示モード #
ツールバーのコントロールで、すべてのテーブルの表示を All(全カラム)、
PK/FK(主キー・外部キーのみ)、Name(テーブル名のみ、カラムなし)の
いずれかに切り替えられます。各ノードにも独自の ▤ ボタンがあり、そのテーブルだけの
表示モードを個別に切り替えられます — 1つの大きなテーブルだけを詳しく見つつ、残りはコンパクトに保ちたい
ときに便利です。全体のモードを切り替えると、テーブルごとの個別設定はリセットされます。
論理名 #
テーブルの DB コメントは、検索可能な「論理名」を兼ねます — 例えば users(Customer accounts)
のように表示されます。ツールバーのトグルで、ライブビューの表示を Both / Physical /
Logical のいずれかに切り替えられます。エクスポートにはエクスポートパネル内に独自の、
独立した Both/Phys./Log. の選択肢があります(エクスポート参照)— 今見ている表示を
変えても、エクスポートされる内容は変わりません(その逆も同様です)。
名前付きビューと共有 #
💾 Save は名前の入力を求め、現在のビューをその名前で保存します (既存の名前を指定すると上書きされます)。保存されるビューには、除外テーブル、禁止テーブル、 Auto-expand、depth、direction、カラム表示モード、そして現在表示中の各テーブルの位置が含まれます。
Views… ドロップダウンから保存済みビューを読み込むか、🗑
で削除できます。🔗 は共有リンクをコピーします —
現在のビューを JSON エンコードしてページ自身の URL に付加したものです。そのリンクを開くと自動的に
同じビューが再現されるので、PR の説明文やチャットにそのまま貼り付けられます。
エッジの種類 #
図には3種類の関連が反映されますが、キャンバス上の線のスタイルは2種類しかなく、 残りは Details ペインのバッジで区別されます。
- 実線 — デフォルト:
--modelsによる宣言済みの association、または実際の DB FK 制約。キャンバス上ではこの2つは同じ見た目です。Details ペインの関連一覧では、制約に基づくエッジには DB FK バッジが付き、単なる宣言済み association にはバッジが付きません。 - 破線 — 多対多の関連(join テーブル経由でしか到達できないもの /
has_and_belongs_to_many/through。直接のbelongs_to/has_oneがない場合)。 - 薄い点線 —
--infer-fkによる名前ベースの推測。そのエッジを支える association がすべて推測によるものである場合のみ表示されます。Details ペインには inferred バッジが付きます。カラム一覧の「FK」バッジは、推測だけでは決して付与されません — 実際の association がある場合のみです。
manual バッジは、設定ファイルの relations
から来た association を示します。(破線のエッジとは別に)破線のノードの枠は、そのテーブルが
直接チェックされたのではなく Auto-expand によって引き込まれたことを示します。
キーボードショートカット #
これが全リストです — ズーム、保存、エクスポートにショートカットはありません。ツールバーの ? ボタンから、このショートカット一覧の簡易版と、マウス操作の説明、 そしてこのマニュアルへのリンクをビューア内で直接確認できます。
| キー | 動作 |
|---|---|
| Esc | 状況に応じて、次の優先順で実行されます: 開いているツールバーのメニュー(Export または ? help)を閉じる → フィルタボックスにフォーカスがあり空でなければクリア → ハイライトボックスも同様にクリア → フォーカスモードを終了 → それ以外の場合はすべての選択を解除 |
| Ctrl/Cmd+Z | 直前のレイアウト変更を取り消す |
| Ctrl/Cmd+Shift+Z または Ctrl/Cmd+Y | やり直す |
| Enter(フィルタボックス内) | 最有力候補のテーブル/カラムにジャンプ |
| Enter / Shift+Enter(ハイライトボックス内) | 次/前の一致に移動 |
ダークモード #
🌙 ツールバーボタンで図のダークモードを切り替えます。これは手動での切り替えのみです —
ビューアは OS/ブラウザのカラースキームを自動的には追従しません — 選択内容は次回開いたときのために
ブラウザに記憶されます。エクスポート(PNG/SVG)は、現在どちらのモードで見ていても常にライトパレットで
描画されます。
印刷 #
専用の印刷ボタンはありません — ブラウザ自体の印刷コマンド(Ctrl/Cmd+P)を使ってください。 印刷用のスタイルシートがすべてのクロム(ペイン、ツールバー、凡例、フォーカスバー)を自動的に隠し、 プレーンな白背景に図だけを残します。
エクスポート #
ツールバーの ⬇ Export ボタンを押すと、上部に画像オプション、下部に フォーマットごとの行が並んだパネルが開きます。各行には Copy と Download の別々のボタンがあります — 画像をクリップボードに書き込めるブラウザであっても、 ファイル保存という選択肢を奪わないよう、コピーとダウンロードは意図的に別のアクションとして分離されています。
エクスポートパネル: 上部に画像オプション、下部にフォーマットごとの Copy/Download 行。
画像オプション PNG / SVG のみ
これら2つのチェックボックスと1つのトグルは、PNG と SVG のエクスポートにのみ適用されます — Mermaid、PlantUML、Excel ワークブックには影響しません。
- Join-table labels(⇢)— デフォルトでオン。オフにすると、エクスポートした画像から 「join テーブル経由」を示す小さなエッジラベルを除外します。
- ✓ root badges — デフォルトでオフ。オンにすると、エクスポートした画像から Auto-expand の起点を示すチェックマークバッジを除外します。
- Names: Both / Phys. / Log. — ツールバーにあるライブビュー自体の名前表示モードとは 独立しています(ビューアガイド参照)。自分は物理名で見ながら、 ステークホルダー向けの資料には論理名だけをエクスポートする、といった使い方ができます。
ライブのハイライト検索は、PNG と SVG のどちらのエクスポートにも引き継がれます (常に取り除かれるテーブル/エッジの選択状態とは異なります)— ハイライトされた図をそのまま ドキュメントに貼り付けられるようにするためです。
PNG
図をまず SVG として描画し、オフスクリーンの <canvas> に読み込んでから、
最大2倍のスケールでラスタライズします — canvas のサイズが約8000pxを超えそうな場合は
(それより下に)クランプされます。ブラウザは canvas サイズの上限をそれよりずっと低く設定していることが多く、
超えると toBlob() がサイレントに失敗するためです。Copy は直接クリップボードに
書き込み、ブラウザが画像をクリップボードに書き込めない場合は自動的にファイルダウンロードにフォールバック
します。Download は常にファイルを保存します。
SVG
Copy は生の SVG マークアップをテキストとしてコピーします(失敗した場合はダウンロードに
フォールバック)。Download は .svg ファイルを保存します。エクスポートされる
SVG は、ライブビューの現在のダーク/ライト設定に関わらず、常にライトカラーパレットを使用します。
Mermaid
現在表示されているものをすべてカバーする erDiagram ブロックを生成します —
フォーカス、非表示、除外の各状態がすべて反映されるため、必ずしもスキーマ全体になるとは限りません。
各テーブルはカラム名・型・PK/FK マーカーを列挙するエンティティブロックになり、各エッジは Mermaid の
鳥の足記法(crow's-foot)を使った関連の行になり、最初の association の名前がラベルとして付きます。
カラムのコメント、null 許可、デフォルト値、論理名は Mermaid の出力には含まれません — 含まれるのは
名前・型・キーマーカーのみです。
PlantUML
Mermaid と同じ範囲・制限(現在表示中のテーブルのみ、カラムコメントなし)ですが、エンティティの
マークアップは異なります: 主キーのカラムが区切り線の上に先頭でリストされ、null 非許可のカラムには
* が付き、外部キーのカラムには <<FK>> が付き、テーブルに論理名が
あれば物理名の横に全角括弧で表示されます。
Excel ワークブック
--excel FILE.xlsx は、外部のスプレッドシートライブラリを一切使わずにワークブックを
書き出します。
- 概要シート — テーブルごとに1行:
#、Table(そのテーブル 自身のシートへのハイパーリンク付き)、Comment、Columns(カラム数)、Indexes(インデックス数)、Missing schema。 - テーブルごとのシート — テーブル名とコメント、続いてカラムの表(
#、Column、Type、Nullable、Default、Key—PK/FK/空欄、Extra、Comment)、インデックスがあれば Indexes セクション(名前、カラム、unique の有無)、association があれば Associations セクション(種類、名前、参照先、そしてその出所:DB FK/inferred/manual/code)。
--excel-template FILE.xlsx を使うと、erdscope 自体のコードに触れることなく、ワークブックの
色・フォント・罫線を5セル契約を通じて再スタイルできます: テンプレートの最初のワークシート
の A 列、1〜5行目に、それぞれ Title / Header / Data / Data (alternate row) / Section のスタイルを
設定しておく必要があります。読み取られるのは各セルのスタイル(フォント、塗りつぶし、罫線)だけで、
セルのテキスト内容は関係ありません。契約セルが欠けている場合は、その1つのロールだけ erdscope 組み込みの
スタイルにフォールバックし、stderr に警告が出力されます。.xlsx としてまったく開けない
ファイルだけがハードエラーになります。
このリポジトリには
excel-template.xlsx
(gen_excel_template.py によって生成)が、すぐに編集できる出発点として同梱されています —
そのStylesシートには、5つの契約セルが erdscope 標準のスタイルであらかじめ設定されており、
B 列には各ロールの平易な説明があります。
--excel-template は --excel なしでは効果がありません — スタイル対象となる
--excel を指定せずにテンプレートを渡した場合、erdscope は stderr に警告を出力し、それ以外は
無視します。トラブルシューティング / FAQ #
日本語(またはマルチバイト)のコメントが文字化けする
erdscope は PyMySQL 経路でも mysql CLI フォールバック経路でも、明示的に
utf8mb4 で接続します — サーバーやセッションのデフォルト文字セットには頼りません。それでも
コメントが化けている場合、最も可能性が高いのは、データベースに書き込まれた時点ですでに壊れていた
というケースです(例えば以前に utf8mb4 でない接続経由でインポートされた場合など)—
erdscope のバグだと判断する前に、utf8mb4 であることが確実なクライアントで、データベース内の
コメントを直接確認してみてください。
PyMySQL / psycopg がインストールされていない場合はどうなりますか?
erdscope は代わりにデータベース自身の CLI にシェルアウトします — MySQL なら mysql、
PostgreSQL なら psql(クエリを COPY … TO STDOUT でラップします。このエスケープ
済みテキスト形式のおかげで、自由記述のコメントが出力を壊すことがありません)。どちらも PATH
上にある必要があります。パスワードはこの場合も MYSQL_PWD / PGPASSWORD 環境変数
経由で渡され、CLI 引数として渡されることはありません。この2つの経路は、バイト単位で同一の HTML を生成
します。ドライバと CLI のどちらも利用できない場合は、どちらかをインストールするよう促す明確な
エラーが表示されます — erdscope がここでサイレントに失敗することはありません。
VIEW が図に表示されないのはなぜですか?
これは仕様です — erdscope は実際にストレージに裏付けられたテーブルのみを読み込みます: MySQL では
TABLE_TYPE = 'BASE TABLE'、PostgreSQL では通常のテーブルとパーティション親テーブルのみ
(VIEW も個々のパーティションも対象外)です。これにより、図は実際にストレージに裏付けられたスキーマに
絞り込まれます。
--infer-fk がデフォルトでオフなのはなぜですか?
単なる *_id というカラム名は推測にすぎず、それを裏付けるもの(実際の association や
DB FK 制約)が何もない場合、間違っている可能性があるためです。このフラグをオンにしても、その推測が
遡って昇格するわけではありません — カラム一覧の「FK」バッジと PK/FK カラム表示モードは、あくまで実際の
association だけに基づいており、推測によるエッジは常に見た目でも区別されます(薄い点線になります。
エッジの種類参照)。検証済みの関連と同じ見た目になることはありません。
--table-map はどんなときに必要ですか?
これは Rails 専用の抜け道で、erdscope の静的解析ではモデルの実際のテーブルを特定できない、まれな
ケースのためのものです — 最も多いのは、アプリ自身にはソースがなく、gem から提供される
concern モジュールの中に self.table_name = ... の代入がある場合です。
--table-map 'Widget=crm_widgets'(繰り返し指定可、カンマ区切りリストも可)を渡すことで
明示的に上書きできます。この上書きは、そのモデルを指す他のモデルの association も修正するため、
右ペインのリンクは正しいテーブルに解決されます。
Auto-expand がオンなのに関連テーブルが表示されません
Auto-expand は、チェック済み/フォーカス中の起点から BFS(幅優先探索)でたどり着けるテーブルだけを 引き込みます。この探索が途中で止まる正当な理由がいくつかあります — 順に確認してみてください。
- Direction(方向)フィルタ(
Deps/Dependents)が、実際の関連の向きと一致していない可能性があります。 - 対象のテーブルが禁止(Ban)(
🚫)されている可能性があります — 禁止されたテーブルは、単なる通過点としてであっても Auto-expand が決して越えません。 - Depth(深度)の上限が、そのホップ数に対して浅すぎる可能性があります。
- ノードの
⊕ボタンでそのテーブルを引き込んだ場合、それは意図的に新しい Auto-expand の起点にはならないため、そこからさらに自動的に広がることはありません。 - 生成時に
--only/--excludeでそもそも図の対象外になっている場合、そのテーブルは単純に図のどこにも存在しません。
拡張 #
パース以降のすべて — HTML/JS ビューア、レイアウト、すべてのエクスポート形式 — は、erd.py
自身のモジュール docstring に記載されている、単一の中間表現(IR)を消費します。
tables = {
"table_name": {
"primary_key": "id" | None,
"comment"?: str,
"schema_missing"?: bool, # model exists but no DB table
"columns": [{"name","type","nullable","primary",
"sql_type"?, "default"?, "extra"?, "comment"?}],
"indexes": [{"name","columns":[...],"unique":bool}],
"associations": [{"type": has_many|belongs_to|has_one|has_and_belongs_to_many,
"name", "target",
"through"?, "foreign_key"?, "polymorphic"?,
"db_fk"?, "inferred"?}],
}
}
新しいソースデータベースへの対応は、この同じ形を生成するパーサーを1つ追加するだけです。
parse_postgres() は、そのパターンの実例です — pg_catalog のクエリ結果を、
MySQL アダプタの IR ビルダーが受け取るのとまったく同じ行の形に整形します。そのため PK の検出、
unique インデックスによる 1:1 昇格、インデックスの組み立てはコードを複製せず共有されています —
アダプタ全体は、4つのクエリと接続処理だけで成り立っています。SQL 型の短縮表にはすでに両エンジン
由来の型名(character varying、bigserial、jsonb、
bytea、inet など)が含まれているため、さらに別のエンジンに対応する場合も、
基本的にはそのカタログを同じ5カラムの行の形にマッピングするだけで済みます。