Turn a DBML schema into an ER diagram
Paste a DBML schema, get an editable ER diagram, edit it, and get DBML back out — with the parser's limits named up front.
If you already have a schema in DBML — the text format dbdiagram.io uses — you can paste it into diagrams.info and get an editable ER diagram out of it. No account, no install, and the schema stays in your browser.
Before the steps, the limits, because a tool that silently drops half your file is worse than one that refuses it.
What comes across, and what doesn’t
| DBML | What happens |
|---|---|
Table … { } and its columns | A table, one row per column, each column’s type text kept as written |
[pk] | Marked PK on that row |
Inline [ref: > Other.id] | A connector from this row to the referenced row; this row is marked FK |
Ref: A.a > B.b, and the Ref { … } block form | Same — a row-to-row connector |
<, > and - in a ref | Read for direction. The foreign-key side is normalised to be the connector’s source |
[unique] | Parsed, but the diagram has nowhere to show it, and it does not survive an export |
Enum … { } | Read past. No enum shape is drawn. A column typed with an enum keeps the enum’s name as its type text, and that is all |
Indexes { … } | Skipped, deliberately, so index expressions don’t become phantom columns |
Note, TableGroup, Project | Parsed past and ignored. Nothing is drawn |
Other column settings — increment, not null, default | Ignored |
That list is the whole of it. The parser is not a full DBML implementation; it covers the subset that has a picture to draw.
1. Open the editor
Go to diagrams.info. It opens straight onto a canvas; dismiss the welcome panel. One thing to know first: the editor is mouse-only. There are no touch handlers in it yet, so this is a desktop workflow.
2. Paste the schema
Click Import in the top bar. In the dialog, choose Database — tables as DBML (the other tab, Diagram, is for whole-board JSON), stay on Import, and paste:
Table users {
id int [pk]
email varchar [unique]
created_at timestamp
}
Table posts {
id int [pk]
user_id int [ref: > users.id]
title varchar
body text
}
Table comments {
id int [pk]
post_id int [ref: > posts.id]
author_id int [ref: > users.id]
body text
} Load file… accepts .dbml, .txt and .sql, but only reads the file as text — the parser is still
DBML, so a raw CREATE TABLE dump imports nothing and you get “No tables found.”
Click Generate diagram. You should see “Imported 3 tables and 3 relationships.”
3. What you got
Three table boxes, laid out in a rough square near the top-left of the area you are looking at, packed so
taller tables don’t leave gaps. Each row shows the column name, its type, and a key badge: PK for a [pk] column, FK for any column on the referencing side of a ref.
The relationships are row-to-row connectors: the line starts at posts.user_id and ends at users.id,
not at the edge of the box. Move a table and the line stays attached to the right rows.
The import merges into whatever is already on the canvas rather than replacing it, and the whole thing
goes in as a single undo step. One Ctrl+Z (or Cmd+Z) removes every table and every connector it just
created.
4. Add cardinality
Imported connectors are plain lines: crow’s-foot markers are a styling choice, and the import does not
guess them for you. Click a connector to select it. Its toolbar has a Relationship dropdown with a
marker per end — —, 1, N, 0..1, 0..N — plus presets that set both ends at once: 1 — 1, 1 — N, N — N. For posts.user_id → users.id you want 1 — N, with the 1 at the users end.
5. Edit the tables
Imported tables are ordinary diagram elements, so they behave like one you drew by hand:
- Rename by double-clicking the title bar; drag that same bar to move the table.
- Edit a cell by clicking it and typing —
columnandtypeare plain text inputs. - Toggle a key by clicking the badge at the end of the row. It cycles
—→PK→FK. - Add a row with + Add row, or by pressing
Tabout of the last row’s type field. - Remove a row with the
×. Any connector attached to it goes too. - Link two rows by dragging one table’s row onto a row in another table.
6. Get DBML back out
Click Export in the top bar, pick Database — tables as DBML, and the current board comes back as DBML — Copy, or Download .dbml. Two things before you rely on the round trip:
- Only table elements and row-to-row connectors are exported. A plain box-to-box line between two
tables is not a relationship to the exporter, and produces no
Ref. - What does not survive:
unique, enums, indexes, notes, and everything else from the table above. A column with no type is written asvarchar; names that aren’t plain identifiers get double-quoted, and duplicate table or column names are suffixed_2,_3so the output stays valid.
Edge cases in the parser
Worth knowing if a ref quietly fails to appear:
- A composite ref —
Ref: a.(x, y) > b.(p, q)— uses the first column on each side only. - A schema qualifier is dropped:
public.users.idis read asusers.id. - A table alias (
Table users as U) is not tracked, so a ref written againstUwill not resolve. - Two tables with the same name: the first definition wins, the second is ignored.
The first two are usually harmless: a composite ref still draws, on its first column, and a qualified name still resolves. The last two lose something silently — a ref against an alias never draws, and a duplicated table name means the second block simply isn’t there.
Where the diagram lives
In your browser. The board is saved to localStorage about a second after you stop editing, there is no
account, and the schema you pasted is never sent anywhere — useful if it is one you are not allowed to paste
into a hosted tool. The obvious cost: clear your site data and it is gone. Use Export → Diagram for a
JSON file you can re-import, and keep the .dbml.