See it as a diagram
Everything below, as a diagram you can edit. Describe yours and see it in seconds.
No account needed · Editable canvas, not a picture
The migration is the change event
Whatever your stack, schema changes arrive as files in one directory: V42__add_invoices.sql for Flyway, a timestamped revision under alembic/versions, a folder under prisma/migrations. That gives CI a perfect filter. A workflow that runs only when the migrations path changes fires on exactly the merges that can invalidate the ER diagram, and never otherwise.
This is the difference between "keep the diagram up to date", a chore with no deadline, and "the diagram regenerates when a migration merges", a mechanism. Chores lose to sprint pressure every time; mechanisms do not ask.
Diff tools prove when the diagram lies
Before automating regeneration, it helps to measure the current drift. migra diffs two Postgres schemas and emits the ALTER statements separating them, so running it between production and the schema your diagram was drawn from quantifies the lie precisely. atlas schema diff does the same across more engines, comparing live databases, migration directories, or HCL definitions in any combination.
For docs specifically, tbls has the check built in: tbls diff compares the generated schema docs against the live database and exits non-zero when they disagree, which turns "is our ER documentation current" into a CI assertion rather than an opinion.
Generate from the live connection or from DDL
Two mature open-source generators draw the diagram from the database itself. SchemaSpy connects over JDBC and produces browsable HTML with relationship diagrams rendered via Graphviz. tbls connects with a DSN in a small .tbls.yml, writes Markdown docs per table plus an ER diagram, and is small enough to run in any CI image. Both inherit foreign keys automatically; both also inherit the layout limitations of automatic rendering on large schemas.
Datadef takes the text route: paste your DDL, a schema dump, or migration files as the prompt and it generates an editable ER diagram you can rearrange, annotate, and zone by domain. The ERD from SQL generator is the first-run entry point; the ongoing loop is what the next section wires up. The DDL-specific details live in living diagram from SQL DDL.
# .tbls.yml: docs and drift check from the live connection dsn: postgres://readonly:[email protected]:5432/app docPath: docs/schema # In CI, after any merge touching db/migrations/**: tbls diff # exits non-zero when docs/schema lags the database tbls doc --force # regenerate the per-table docs and ER diagram
Regenerate on merge, embed everywhere
The full loop has three parts. Trigger: a CI workflow filtered on the migrations path. Regeneration: an AI agent connected to the Datadef MCP server (registry name io.datadef/mcp) reads the merged migration and updates the ER diagram to match; it runs as a CI step or on request during review, and needs an API key, available on paid plans. Propagation: the diagram, shared public, is embedded by URL in Confluence, Notion, or the README, so every copy shows the new version within minutes of the update without anyone re-exporting an image.
The judgment call of when regeneration is worth running at all, every migration versus meaningful ones, is discussed in when to regenerate an architecture diagram; for ER diagrams the honest answer is nearly always, because a single dropped column makes the picture wrong.
The caveats on regeneration
Nothing here is automatic in the marketing sense. Datadef does not connect to your database and does not watch the migrations directory; the trigger is your CI workflow and the update is one agent call inside it. The live embed exists only while the project is shared public, which can be wrong for schemas that are themselves sensitive; a regenerated export committed to the repo is the private-schema fallback.
Automatic generators have their own honest limit worth naming: past a few dozen tables, machine layout degrades into spaghetti. The practical pattern is a generated-then-curated diagram, zoned by domain, that an agent updates incrementally rather than relaying out from scratch each time.
FAQ
How do I keep an ER diagram up to date automatically?
How can I check whether my ER diagram matches the database?
What tools generate an ER diagram from an existing database?
Should the ER diagram live in the repo or in a diagram tool?
Why do auto-generated ER diagrams become unreadable on large schemas?