erdscope 0.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- erdscope-0.1.0/LICENSE +21 -0
- erdscope-0.1.0/PKG-INFO +178 -0
- erdscope-0.1.0/README.md +147 -0
- erdscope-0.1.0/erd.py +5068 -0
- erdscope-0.1.0/erdscope.egg-info/PKG-INFO +178 -0
- erdscope-0.1.0/erdscope.egg-info/SOURCES.txt +12 -0
- erdscope-0.1.0/erdscope.egg-info/dependency_links.txt +1 -0
- erdscope-0.1.0/erdscope.egg-info/entry_points.txt +2 -0
- erdscope-0.1.0/erdscope.egg-info/requires.txt +10 -0
- erdscope-0.1.0/erdscope.egg-info/top_level.txt +1 -0
- erdscope-0.1.0/pyproject.toml +41 -0
- erdscope-0.1.0/setup.cfg +4 -0
- erdscope-0.1.0/tests/test_e2e.py +1989 -0
- erdscope-0.1.0/tests/test_erd.py +1453 -0
erdscope-0.1.0/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 orapli
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
erdscope-0.1.0/PKG-INFO
ADDED
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: erdscope
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Interactive, self-contained ER-diagram HTML and Excel table definitions from a live MySQL database — single file, zero required dependencies
|
|
5
|
+
Author: tas6
|
|
6
|
+
License-Expression: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/orapli/erdscope
|
|
8
|
+
Project-URL: Documentation, https://orapli.github.io/erdscope/manual.html
|
|
9
|
+
Project-URL: Live demo, https://orapli.github.io/erdscope/
|
|
10
|
+
Project-URL: Repository, https://github.com/orapli/erdscope
|
|
11
|
+
Project-URL: Issues, https://github.com/orapli/erdscope/issues
|
|
12
|
+
Keywords: erd,er-diagram,database,schema,mysql,rails,prisma,django,documentation
|
|
13
|
+
Classifier: Development Status :: 4 - Beta
|
|
14
|
+
Classifier: Environment :: Console
|
|
15
|
+
Classifier: Intended Audience :: Developers
|
|
16
|
+
Classifier: Programming Language :: Python :: 3
|
|
17
|
+
Classifier: Topic :: Database
|
|
18
|
+
Classifier: Topic :: Documentation
|
|
19
|
+
Classifier: Topic :: Software Development :: Documentation
|
|
20
|
+
Requires-Python: >=3.9
|
|
21
|
+
Description-Content-Type: text/markdown
|
|
22
|
+
License-File: LICENSE
|
|
23
|
+
Provides-Extra: mysql
|
|
24
|
+
Requires-Dist: PyMySQL; extra == "mysql"
|
|
25
|
+
Provides-Extra: yaml
|
|
26
|
+
Requires-Dist: PyYAML; extra == "yaml"
|
|
27
|
+
Provides-Extra: all
|
|
28
|
+
Requires-Dist: PyMySQL; extra == "all"
|
|
29
|
+
Requires-Dist: PyYAML; extra == "all"
|
|
30
|
+
Dynamic: license-file
|
|
31
|
+
|
|
32
|
+
# erdscope
|
|
33
|
+
|
|
34
|
+
Generate a **self-contained, interactive ER diagram** — and an **Excel table-definition
|
|
35
|
+
workbook** — from a live MySQL database, with a single-file, zero-dependency Python CLI.
|
|
36
|
+
|
|
37
|
+
The database is the source of truth (tables, columns, comments, indexes, real foreign
|
|
38
|
+
keys). Application code (Rails / Prisma / Django) can optionally be layered on top to
|
|
39
|
+
add association semantics the database cannot express (`has_many :through`,
|
|
40
|
+
polymorphic, ...).
|
|
41
|
+
|
|
42
|
+
## Demo
|
|
43
|
+
|
|
44
|
+
**[Try the live demo →](https://orapli.github.io/erdscope/)** — a small e-commerce
|
|
45
|
+
schema with comments, indexes, real FKs and an inferred relation. Everything below
|
|
46
|
+
is one self-contained HTML file.
|
|
47
|
+
|
|
48
|
+
[](https://orapli.github.io/erdscope/)
|
|
49
|
+
|
|
50
|
+
Regenerate it anytime with `python3 docs/gen_demo.py`.
|
|
51
|
+
|
|
52
|
+
**[Read the user manual →](https://orapli.github.io/erdscope/manual.html)** — installation,
|
|
53
|
+
CLI/config reference, a full viewer guide, and troubleshooting. ([日本語版 →](https://orapli.github.io/erdscope/manual.ja.html))
|
|
54
|
+
|
|
55
|
+
## Usage
|
|
56
|
+
|
|
57
|
+
```bash
|
|
58
|
+
python3 erd.py mysql://readonly@127.0.0.1:3306/myapp_production -o erd.html
|
|
59
|
+
|
|
60
|
+
# enrich with association semantics parsed from application code (optional)
|
|
61
|
+
python3 erd.py mysql://readonly@127.0.0.1:3306/myapp_production \
|
|
62
|
+
--models /path/to/rails/app -o erd.html
|
|
63
|
+
|
|
64
|
+
# also write a table-definition workbook
|
|
65
|
+
python3 erd.py mysql://readonly@127.0.0.1:3306/myapp_production \
|
|
66
|
+
--excel table_definitions.xlsx -o erd.html
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
Behind a bastion? Open an SSH tunnel first and point at localhost:
|
|
70
|
+
|
|
71
|
+
```bash
|
|
72
|
+
ssh -N -L 3307:db-host:3306 bastion &
|
|
73
|
+
python3 erd.py mysql://readonly@127.0.0.1:3307/myapp_production -o erd.html
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
Use a read-only account, and leave the password out of the URL — if it's not in
|
|
77
|
+
`MYSQL_PWD` either, you'll be prompted for it (hidden input, never touches argv or
|
|
78
|
+
shell history). See [Dependencies](#dependencies) below for how the DB connection
|
|
79
|
+
itself is made.
|
|
80
|
+
|
|
81
|
+
### Options
|
|
82
|
+
|
|
83
|
+
| Option | Description |
|
|
84
|
+
|---|---|
|
|
85
|
+
| `-o FILE` | Output HTML path (default: `erd.html`) |
|
|
86
|
+
| `--models PATH` | Merge associations parsed from code: a Rails project (or `app/models` dir), a `schema.prisma`, or a Django project — auto-detected |
|
|
87
|
+
| `--excel FILE.xlsx` | Also write a table-definition workbook: an overview sheet plus one sheet per table (columns, defaults, keys, comments, indexes, associations) |
|
|
88
|
+
| `--excel-template FILE.xlsx` | Override the workbook's colors/fonts/borders from a template `.xlsx` — see `excel-template.xlsx` and its `Styles` sheet for the 5-cell contract (default: built-in styling) |
|
|
89
|
+
| `--max-rows N` | Max column rows shown per table (default: 15; the rest scroll) |
|
|
90
|
+
| `--only 'user*,post*'` | Include only tables matching the glob pattern(s) |
|
|
91
|
+
| `--exclude '*_logs'` | Exclude tables matching the glob pattern(s) |
|
|
92
|
+
| `--infer-fk` | Guess relations from `*_id` column names when no real association/FK backs them (off by default — see below) |
|
|
93
|
+
| `--table-map 'Widget=crm_widgets'` | Rails only: override a model's table when static analysis can't determine it (e.g. `table_name` set inside a concern that lives in a gem, not the app). Repeatable; comma-separated lists accepted |
|
|
94
|
+
| `--config PATH` | Load defaults from a config file instead of repeating flags — see below. Auto-discovered as `.erdscope.json`/`.yml`/`.yaml` in the current directory if not given |
|
|
95
|
+
| `--no-config` | Skip config auto-discovery even if `.erdscope.*` exists in the cwd |
|
|
96
|
+
|
|
97
|
+
## Config file
|
|
98
|
+
|
|
99
|
+
Once the flag list above gets long, put it in a config file instead — `.erdscope.json`
|
|
100
|
+
(or `.yml`/`.yaml` with PyYAML) next to where you run the tool is picked up automatically.
|
|
101
|
+
Most keys mirror a CLI option (an explicit flag always wins over the config); the DB
|
|
102
|
+
connection is config-only as `host`/`port`/`user`/`database` — deliberately with no
|
|
103
|
+
password field — and `relations` manually declares relations no FK, code, or inference
|
|
104
|
+
can find. See the [Config file chapter of the manual](https://orapli.github.io/erdscope/manual.html#config-file) for the full key
|
|
105
|
+
list and semantics, and [`erdscope.example.yml`](erdscope.example.yml) for a fully
|
|
106
|
+
annotated sample based on the live demo's schema.
|
|
107
|
+
|
|
108
|
+
## Dependencies
|
|
109
|
+
|
|
110
|
+
`erd.py` runs with **zero required dependencies** — everything below is optional, and
|
|
111
|
+
the tool degrades gracefully (falls back, or fails with a clear message) when a piece
|
|
112
|
+
is missing.
|
|
113
|
+
|
|
114
|
+
| Library | Used for | If not installed |
|
|
115
|
+
|---|---|---|
|
|
116
|
+
| [PyMySQL](https://pypi.org/project/PyMySQL/) | The DB connection | Falls back to shelling out to the `mysql` CLI (must be on `PATH`) |
|
|
117
|
+
| [PyYAML](https://pypi.org/project/PyYAML/) | Reading a `.yml`/`.yaml` config file | A `.json` config still works with no dependency; pointing `--config`/auto-discovery at a `.yml`/`.yaml` file without PyYAML installed exits with a clear error |
|
|
118
|
+
|
|
119
|
+
Excel output (`--excel`) needs neither — it's written directly via the stdlib
|
|
120
|
+
`zipfile`/XML, not a spreadsheet library.
|
|
121
|
+
|
|
122
|
+
Test-only, and only if you run that particular suite:
|
|
123
|
+
|
|
124
|
+
| Library | Used for |
|
|
125
|
+
|---|---|
|
|
126
|
+
| [openpyxl](https://pypi.org/project/openpyxl/) | Roundtrip-verifying `--excel` output in the unit tests (`tests/test_erd.py`); that one test skips itself if it's missing |
|
|
127
|
+
| [Playwright](https://playwright.dev/python/) | The browser E2E suite (`tests/test_e2e.py`) — see [Tests](#tests) below |
|
|
128
|
+
|
|
129
|
+
## What you get
|
|
130
|
+
|
|
131
|
+
Feature highlights — each link goes to the relevant [manual](https://orapli.github.io/erdscope/manual.html) chapter:
|
|
132
|
+
|
|
133
|
+
- **Database truth** — tables, columns (full SQL types, defaults, extras), table and
|
|
134
|
+
column comments, indexes, and real FK constraints, read from `information_schema`
|
|
135
|
+
- **Code semantics on top** — `--models` merges Rails / Prisma / Django associations;
|
|
136
|
+
declared, DB-FK, and inferred edges stay [visually distinct](https://orapli.github.io/erdscope/manual.html#viewer-edges)
|
|
137
|
+
- **[Interactive exploration](https://orapli.github.io/erdscope/manual.html#viewer-guide)** — focus with depth and dependency
|
|
138
|
+
direction, two-level hiding, table *and column* search (with regex/case toggles), a
|
|
139
|
+
non-filtering Highlight search that survives into exports, named views, share links
|
|
140
|
+
- **[Readable layouts](https://orapli.github.io/erdscope/manual.html#viewer-layout)** — viewport-aware packing with crossing
|
|
141
|
+
reduction, drag-to-snap with guide lines, multi-select align/distribute, Auto-tidy,
|
|
142
|
+
layout undo/redo
|
|
143
|
+
- **[Exports](https://orapli.github.io/erdscope/manual.html#exports)** — PNG (2x), SVG, Mermaid, and PlantUML, each with its own
|
|
144
|
+
copy and download buttons and image options, plus the Excel workbook
|
|
145
|
+
(customizable via `--excel-template`)
|
|
146
|
+
- **[Logical names](https://orapli.github.io/erdscope/manual.html#viewer-names)** — a table's DB comment doubles as a searchable
|
|
147
|
+
logical name (e.g. `users(Customer accounts)`), with independent display modes for
|
|
148
|
+
the live view and exports
|
|
149
|
+
- **Extras** — dark mode, print stylesheet, resizable/collapsible panes
|
|
150
|
+
|
|
151
|
+
## Tests
|
|
152
|
+
|
|
153
|
+
```bash
|
|
154
|
+
python3 -m unittest discover -s tests -v
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
The IR builders and the Excel writer are covered by pure unit tests; the overlay
|
|
158
|
+
parsers have minimal fixtures under `tests/fixture_*`. No database is required to
|
|
159
|
+
run the tests.
|
|
160
|
+
|
|
161
|
+
`tests/test_e2e.py` drives the generated HTML's client-side JS (grid layout,
|
|
162
|
+
multi-select align/distribute, drag-to-snap, Auto-tidy) in a real headless browser. It's optional and skips
|
|
163
|
+
itself if not set up:
|
|
164
|
+
|
|
165
|
+
```bash
|
|
166
|
+
pip install playwright && playwright install chromium
|
|
167
|
+
python3 -m unittest tests.test_e2e -v
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
## Extending
|
|
171
|
+
|
|
172
|
+
Everything downstream (UI, layouts, exports) consumes the intermediate representation
|
|
173
|
+
documented at the top of `erd.py`. Adding PostgreSQL support means adding one
|
|
174
|
+
`parse_postgres()` that produces that shape.
|
|
175
|
+
|
|
176
|
+
## License
|
|
177
|
+
|
|
178
|
+
MIT
|
erdscope-0.1.0/README.md
ADDED
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
# erdscope
|
|
2
|
+
|
|
3
|
+
Generate a **self-contained, interactive ER diagram** — and an **Excel table-definition
|
|
4
|
+
workbook** — from a live MySQL database, with a single-file, zero-dependency Python CLI.
|
|
5
|
+
|
|
6
|
+
The database is the source of truth (tables, columns, comments, indexes, real foreign
|
|
7
|
+
keys). Application code (Rails / Prisma / Django) can optionally be layered on top to
|
|
8
|
+
add association semantics the database cannot express (`has_many :through`,
|
|
9
|
+
polymorphic, ...).
|
|
10
|
+
|
|
11
|
+
## Demo
|
|
12
|
+
|
|
13
|
+
**[Try the live demo →](https://orapli.github.io/erdscope/)** — a small e-commerce
|
|
14
|
+
schema with comments, indexes, real FKs and an inferred relation. Everything below
|
|
15
|
+
is one self-contained HTML file.
|
|
16
|
+
|
|
17
|
+
[](https://orapli.github.io/erdscope/)
|
|
18
|
+
|
|
19
|
+
Regenerate it anytime with `python3 docs/gen_demo.py`.
|
|
20
|
+
|
|
21
|
+
**[Read the user manual →](https://orapli.github.io/erdscope/manual.html)** — installation,
|
|
22
|
+
CLI/config reference, a full viewer guide, and troubleshooting. ([日本語版 →](https://orapli.github.io/erdscope/manual.ja.html))
|
|
23
|
+
|
|
24
|
+
## Usage
|
|
25
|
+
|
|
26
|
+
```bash
|
|
27
|
+
python3 erd.py mysql://readonly@127.0.0.1:3306/myapp_production -o erd.html
|
|
28
|
+
|
|
29
|
+
# enrich with association semantics parsed from application code (optional)
|
|
30
|
+
python3 erd.py mysql://readonly@127.0.0.1:3306/myapp_production \
|
|
31
|
+
--models /path/to/rails/app -o erd.html
|
|
32
|
+
|
|
33
|
+
# also write a table-definition workbook
|
|
34
|
+
python3 erd.py mysql://readonly@127.0.0.1:3306/myapp_production \
|
|
35
|
+
--excel table_definitions.xlsx -o erd.html
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
Behind a bastion? Open an SSH tunnel first and point at localhost:
|
|
39
|
+
|
|
40
|
+
```bash
|
|
41
|
+
ssh -N -L 3307:db-host:3306 bastion &
|
|
42
|
+
python3 erd.py mysql://readonly@127.0.0.1:3307/myapp_production -o erd.html
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
Use a read-only account, and leave the password out of the URL — if it's not in
|
|
46
|
+
`MYSQL_PWD` either, you'll be prompted for it (hidden input, never touches argv or
|
|
47
|
+
shell history). See [Dependencies](#dependencies) below for how the DB connection
|
|
48
|
+
itself is made.
|
|
49
|
+
|
|
50
|
+
### Options
|
|
51
|
+
|
|
52
|
+
| Option | Description |
|
|
53
|
+
|---|---|
|
|
54
|
+
| `-o FILE` | Output HTML path (default: `erd.html`) |
|
|
55
|
+
| `--models PATH` | Merge associations parsed from code: a Rails project (or `app/models` dir), a `schema.prisma`, or a Django project — auto-detected |
|
|
56
|
+
| `--excel FILE.xlsx` | Also write a table-definition workbook: an overview sheet plus one sheet per table (columns, defaults, keys, comments, indexes, associations) |
|
|
57
|
+
| `--excel-template FILE.xlsx` | Override the workbook's colors/fonts/borders from a template `.xlsx` — see `excel-template.xlsx` and its `Styles` sheet for the 5-cell contract (default: built-in styling) |
|
|
58
|
+
| `--max-rows N` | Max column rows shown per table (default: 15; the rest scroll) |
|
|
59
|
+
| `--only 'user*,post*'` | Include only tables matching the glob pattern(s) |
|
|
60
|
+
| `--exclude '*_logs'` | Exclude tables matching the glob pattern(s) |
|
|
61
|
+
| `--infer-fk` | Guess relations from `*_id` column names when no real association/FK backs them (off by default — see below) |
|
|
62
|
+
| `--table-map 'Widget=crm_widgets'` | Rails only: override a model's table when static analysis can't determine it (e.g. `table_name` set inside a concern that lives in a gem, not the app). Repeatable; comma-separated lists accepted |
|
|
63
|
+
| `--config PATH` | Load defaults from a config file instead of repeating flags — see below. Auto-discovered as `.erdscope.json`/`.yml`/`.yaml` in the current directory if not given |
|
|
64
|
+
| `--no-config` | Skip config auto-discovery even if `.erdscope.*` exists in the cwd |
|
|
65
|
+
|
|
66
|
+
## Config file
|
|
67
|
+
|
|
68
|
+
Once the flag list above gets long, put it in a config file instead — `.erdscope.json`
|
|
69
|
+
(or `.yml`/`.yaml` with PyYAML) next to where you run the tool is picked up automatically.
|
|
70
|
+
Most keys mirror a CLI option (an explicit flag always wins over the config); the DB
|
|
71
|
+
connection is config-only as `host`/`port`/`user`/`database` — deliberately with no
|
|
72
|
+
password field — and `relations` manually declares relations no FK, code, or inference
|
|
73
|
+
can find. See the [Config file chapter of the manual](https://orapli.github.io/erdscope/manual.html#config-file) for the full key
|
|
74
|
+
list and semantics, and [`erdscope.example.yml`](erdscope.example.yml) for a fully
|
|
75
|
+
annotated sample based on the live demo's schema.
|
|
76
|
+
|
|
77
|
+
## Dependencies
|
|
78
|
+
|
|
79
|
+
`erd.py` runs with **zero required dependencies** — everything below is optional, and
|
|
80
|
+
the tool degrades gracefully (falls back, or fails with a clear message) when a piece
|
|
81
|
+
is missing.
|
|
82
|
+
|
|
83
|
+
| Library | Used for | If not installed |
|
|
84
|
+
|---|---|---|
|
|
85
|
+
| [PyMySQL](https://pypi.org/project/PyMySQL/) | The DB connection | Falls back to shelling out to the `mysql` CLI (must be on `PATH`) |
|
|
86
|
+
| [PyYAML](https://pypi.org/project/PyYAML/) | Reading a `.yml`/`.yaml` config file | A `.json` config still works with no dependency; pointing `--config`/auto-discovery at a `.yml`/`.yaml` file without PyYAML installed exits with a clear error |
|
|
87
|
+
|
|
88
|
+
Excel output (`--excel`) needs neither — it's written directly via the stdlib
|
|
89
|
+
`zipfile`/XML, not a spreadsheet library.
|
|
90
|
+
|
|
91
|
+
Test-only, and only if you run that particular suite:
|
|
92
|
+
|
|
93
|
+
| Library | Used for |
|
|
94
|
+
|---|---|
|
|
95
|
+
| [openpyxl](https://pypi.org/project/openpyxl/) | Roundtrip-verifying `--excel` output in the unit tests (`tests/test_erd.py`); that one test skips itself if it's missing |
|
|
96
|
+
| [Playwright](https://playwright.dev/python/) | The browser E2E suite (`tests/test_e2e.py`) — see [Tests](#tests) below |
|
|
97
|
+
|
|
98
|
+
## What you get
|
|
99
|
+
|
|
100
|
+
Feature highlights — each link goes to the relevant [manual](https://orapli.github.io/erdscope/manual.html) chapter:
|
|
101
|
+
|
|
102
|
+
- **Database truth** — tables, columns (full SQL types, defaults, extras), table and
|
|
103
|
+
column comments, indexes, and real FK constraints, read from `information_schema`
|
|
104
|
+
- **Code semantics on top** — `--models` merges Rails / Prisma / Django associations;
|
|
105
|
+
declared, DB-FK, and inferred edges stay [visually distinct](https://orapli.github.io/erdscope/manual.html#viewer-edges)
|
|
106
|
+
- **[Interactive exploration](https://orapli.github.io/erdscope/manual.html#viewer-guide)** — focus with depth and dependency
|
|
107
|
+
direction, two-level hiding, table *and column* search (with regex/case toggles), a
|
|
108
|
+
non-filtering Highlight search that survives into exports, named views, share links
|
|
109
|
+
- **[Readable layouts](https://orapli.github.io/erdscope/manual.html#viewer-layout)** — viewport-aware packing with crossing
|
|
110
|
+
reduction, drag-to-snap with guide lines, multi-select align/distribute, Auto-tidy,
|
|
111
|
+
layout undo/redo
|
|
112
|
+
- **[Exports](https://orapli.github.io/erdscope/manual.html#exports)** — PNG (2x), SVG, Mermaid, and PlantUML, each with its own
|
|
113
|
+
copy and download buttons and image options, plus the Excel workbook
|
|
114
|
+
(customizable via `--excel-template`)
|
|
115
|
+
- **[Logical names](https://orapli.github.io/erdscope/manual.html#viewer-names)** — a table's DB comment doubles as a searchable
|
|
116
|
+
logical name (e.g. `users(Customer accounts)`), with independent display modes for
|
|
117
|
+
the live view and exports
|
|
118
|
+
- **Extras** — dark mode, print stylesheet, resizable/collapsible panes
|
|
119
|
+
|
|
120
|
+
## Tests
|
|
121
|
+
|
|
122
|
+
```bash
|
|
123
|
+
python3 -m unittest discover -s tests -v
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
The IR builders and the Excel writer are covered by pure unit tests; the overlay
|
|
127
|
+
parsers have minimal fixtures under `tests/fixture_*`. No database is required to
|
|
128
|
+
run the tests.
|
|
129
|
+
|
|
130
|
+
`tests/test_e2e.py` drives the generated HTML's client-side JS (grid layout,
|
|
131
|
+
multi-select align/distribute, drag-to-snap, Auto-tidy) in a real headless browser. It's optional and skips
|
|
132
|
+
itself if not set up:
|
|
133
|
+
|
|
134
|
+
```bash
|
|
135
|
+
pip install playwright && playwright install chromium
|
|
136
|
+
python3 -m unittest tests.test_e2e -v
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
## Extending
|
|
140
|
+
|
|
141
|
+
Everything downstream (UI, layouts, exports) consumes the intermediate representation
|
|
142
|
+
documented at the top of `erd.py`. Adding PostgreSQL support means adding one
|
|
143
|
+
`parse_postgres()` that produces that shape.
|
|
144
|
+
|
|
145
|
+
## License
|
|
146
|
+
|
|
147
|
+
MIT
|