Every schema diagram starts out true and ends up a liar. Someone draws it the week before launch, it earns a proud spot in the wiki, and then the product ships. Twenty migrations later it still shows a users table with no deleted_at, an orders table that has since been split in two, and a relationship that was refactored away in March. New engineers read it, believe it, and build on a picture of a database that no longer exists.
The usual response is guilt: we should have kept it updated. But hand-updating a diagram after every migration is a chore nobody wins, so it never happens. The durable fix is to change where the diagram comes from. If it is generated from the schema instead of maintained alongside it, drift stops being possible, because the picture is always a view of the current truth.
Treat the diagram as derived, not authored
Your schema already lives in a canonical place: the migrations you run and the DDL you can dump from any environment. That is the source of truth, and it is machine-readable. A diagram maintained by hand is a second copy of that truth, and two copies of anything drift. So the move is to make the diagram a projection of the schema, the way a report is a projection of a table, regenerated on demand, never edited into staleness.
In practice that means: whenever you want the current picture, you feed the current schema in and get the diagram out. No manual reconciliation, no "who last touched this," no stale relationships.
Generate from the DDL you already dump
You do not need a special export. Every database can hand you its schema as SQL, and that SQL is exactly what LetDraw reads. On Postgres it is one command; MySQL and others have their own equivalents.
# Postgres: dump just the schema, no data pg_dump --schema-only --no-owner mydb > schema.sql # then: Generate from Code → paste schema.sql → get the ER diagram
Open the Generate from Code dialog, paste the file, and LetDraw builds the diagram: tables with typed columns, primary and foreign keys marked, and one-to-many lines drawn from the REFERENCES clauses with proper crow's-foot heads. What took an afternoon of dragging rectangles is now a paste, and because it came from the real DDL, it is correct by construction.
A diagram you regenerate in ten seconds never goes stale, because nobody has to remember to update it.
Wire it into the workflow so it never drifts
Once generating the diagram is cheap, you can put it where it will stay honest. A few habits that make drift structurally impossible:
- Regenerate on release. Add "refresh the ER diagram from
schema.sql" to your release checklist. It takes longer to read this sentence than to do it. - Diff, don't redraw. When a migration lands, generate a fresh diagram and compare. New table, new column, changed key: the change is visible, and you keep the annotations you added by hand on the parts that did not move.
- Scope to the change. In a review, paste only the tables under discussion. A focused six-table ER diagram that is provably current beats a forty-table poster that might be.
- Keep it as code too. Turn the diagram back into Mermaid or D2 and commit it next to the migration, so the picture travels with the change in the same pull request.
The point of a schema diagram is trust
A schema diagram earns its place only when people believe it without checking. The way to earn that belief is not discipline; it is to remove the human step that goes wrong. Generate the picture from the DDL you already maintain, refresh it whenever the schema moves, and the diagram stops being a museum piece and becomes something the team actually reaches for. Correct by construction, current by default.
Dump your schema, paste it once, and see how close your mental model is to the database you are actually running.