erdify vs. the alternatives¶
Several tools draw ER diagrams for Python projects. They differ less in what they draw than in what they require to run: a live database, an importable application, a Graphviz toolchain — or, for erdify, nothing but the source files.
This page is meant to be useful even when the answer is "use the other one". Every alternative below wins at something erdify deliberately does not do.
At a glance¶
| erdify | paracelsus | eralchemy | sqlalchemy-schemadisplay | erdantic | django-extensions graph_models |
DBML / dbdiagram | |
|---|---|---|---|---|---|---|---|
| Needs a live DB connection | No | No | Optional (a DB URL is one of its inputs) | Optional (or bound metadata) | No | No | Only for db2dbml |
| Imports/executes your code | No — stdlib ast only |
Yes (--import-module, like Alembic) |
Yes (models must import) | Yes | Yes (classes must be importable) | Yes (full Django setup + app registry) | n/a — you write DBML by hand |
| Frameworks read | SQLModel, SQLAlchemy 2.0, Django, Pydantic, dataclasses, SQL DDL | SQLAlchemy | SQLAlchemy (+ live DBs, .er files) |
SQLAlchemy | Pydantic v1/v2, attrs, msgspec, dataclasses | Django | SQL dumps (Postgres, MySQL, MSSQL, Oracle, Snowflake, BigQuery) |
| Runtime dependencies | None (sqlglot only for the sql extra) |
SQLAlchemy, pydot, typer | SQLAlchemy, + Graphviz/pygraphviz for images | SQLAlchemy, pydot, Pillow, Graphviz | pydantic, pygraphviz, typer, … + Graphviz | Django, + pydot/pygraphviz for images | Node.js 18+ |
| System toolchain | None | Graphviz only for image output | Graphviz for image output | Graphviz | Graphviz (pygraphviz builds against it) | Graphviz for image output | Node |
| Text output formats | PlantUML, Mermaid, JSON, standalone HTML | Mermaid, Graphviz .dot |
Mermaid, Graphviz .gv, its own .er markdown |
— (pydot writes images) | Graphviz, D2 | Graphviz .dot, JSON |
DBML, SQL |
| Image output | No (render the PlantUML/Mermaid yourself) | via Graphviz from the .dot |
PNG, PDF, SVG | PNG (+ pydot formats) | PNG, SVG, PDF, … | PNG, SVG, PDF, … | via dbdiagram.io |
| CI drift gate | --check (non-zero exit on a stale diagram) |
--check |
No | No | No | No | No |
| Embeds into Markdown | --inject between markers |
Yes, between markers | No | No | No | No | No |
| License | MIT | MIT | Apache-2.0 | MIT | MIT | MIT | Apache-2.0 |
Versions checked while writing this page: paracelsus 0.15.0, eralchemy 1.7.0,
sqlalchemy-schemadisplay 2.0, erdantic 1.2.1, django-extensions (main),
@dbml/cli 3.x. Please
open an issue if something
here has gone out of date — an inaccurate comparison is worse than none.
The one axis that matters: does it run your code?¶
Everything else on that table follows from this.
erdify parses source with the standard library's ast module. It never
imports your modules, never builds a metadata registry, never opens a
connection. Consequences, good and bad:
- It runs against a repository it cannot install — another team's checkout, a half-migrated branch, a pull request in CI with no services started.
- It has zero runtime dependencies, so it cannot drag a conflicting
SQLAlchemy or pydantic into your environment.
uvx erdify ./appworks on a machine with nothing installed. - Nothing in your models executes, which matters when
models.pyreaches for settings, environment variables or a connection at import time. - It only sees what is written in the file. Anything computed at runtime —
models built by
type(), tables named by an expression, fields attached in a loop — is invisible to it. See Python parsing limitations.
The import-based tools see the real, fully-resolved schema: every mixin
applied, every declared_attr evaluated, every dynamically registered model
present, every type as SQLAlchemy actually resolved it. That is strictly more
accurate — at the price of needing the application to import cleanly, which in
a CI job usually means installing its full dependency tree.
Live introspection (eralchemy against a DB URL, db2dbml) is the most
accurate of all, because it reads what the database really contains, migrations
and all. erdify deliberately does not do this: it answers "what does this code
say?", not "what is deployed?". Those are different questions, and drift between
them is often the thing you want to find.
When to use something else¶
- You want a PNG and do not want to run PlantUML or Mermaid. eralchemy,
sqlalchemy-schemadisplay, erdantic and
graph_modelsall render images directly through Graphviz. erdify emits diagram source and stops there. - You need the deployed schema, not the code. eralchemy against a database
URL, or
db2dbml. - Your models are attrs or msgspec. erdantic supports both; erdify does not.
- Your Django models rely heavily on runtime configuration — swappable user
models, apps assembled from settings, models registered by third-party
packages.
graph_modelssees all of it because Django is actually loaded. - You want to design a schema before writing it. DBML is a DSL you author by hand, and dbdiagram.io gives you a visual editor. It is a modelling tool, not a documentation generator: it does not read Python at all.
- You want a hosted, clickable diagram for non-engineers. dbdiagram.io.
When erdify fits¶
- One tool for a polyglot repository. A Django service, a FastAPI service on
SQLModel, and a
schema.sqlused by the analytics team produce the same diagram format from the same command. Every other tool here covers one framework. - Documentation that cannot silently rot.
--injectwrites the diagram into a Markdown file between markers, and--checkexits non-zero when it drifts, so a stale ERD fails a build instead of quietly misleading the next reader. paracelsus is the only alternative here that does the same; the rest leave keeping the diagram current to you. - Environments where installing the project is not on the table — a docs pipeline, a pre-commit hook, a review of a repository you do not own.
- Diagram-as-text workflows. PlantUML and Mermaid are diffable and review well; Mermaid renders natively on GitHub and GitLab.
- Supply-chain-sensitive installs. Nothing to audit but the standard library.
What erdify does not do, on purpose¶
- No database connection and no introspection of a live schema.
- No image rendering; use PlantUML, Mermaid or their CLIs.
- No round-tripping — erdify reads models and writes diagrams, never the reverse.
- No runtime awareness. If a construct is not visible in the source text, erdify does not see it; the limitations page lists the cases this actually bites.