Convert PostgreSQL schemas to DBML
Inspect real DBML table, index and reference output generated from a PostgreSQL-shaped schema by Trellis’s DBML exporter.
- target
- DBML
- access
- Pro export
- source specimen
- 2 of 13 tables · seed/schema.json
Trellis exports a schema drafted on its canvas using PostgreSQL types. This page does not claim to parse a PostgreSQL dump or a live database.
01 / portable model
Tables first, references after
The DBML exporter carries table descriptions, columns, defaults, key attributes, indexes, rules and questions before writing the reference lines.
// DBML generated from the schema canvas
Table tag {
// One row is one label that can be attached to content. The path column carries the hierarchy, so a child tag can be found by prefix.
id uuid [pk, not null, default: `gen_random_uuid()`]
label citext [not null]
path ltree [not null]
created_at timestamptz [not null, default: 'now()']
// not expressible in DBML: primary key (id)
Indexes { (label) [unique] }
// not expressible in DBML: index using gist (path)
// open question: Should moving a tag rewrite the paths of its descendants, or should reads walk upwards instead?
}
Table article {
// One row is one piece of writing. The current body lives here; every earlier body is a revision row.
id uuid [pk, not null, default: `gen_random_uuid()`]
author_id uuid [not null]
title text [not null]
slug text [not null]
body text [not null, default: '\'\'']
labels text[] [not null, default: '\'{}\'']
search_vector tsvector
published_at timestamptz
created_at timestamptz [not null, default: 'now()']
updated_at timestamptz [not null, default: 'now()']
// not expressible in DBML: primary key (id)
Indexes { (author_id, title) [unique] }
Indexes { (slug) [unique, note: 'published_at is not null'] }
// not expressible in DBML: index using gin (search_vector)
// not expressible in DBML: index (labels) using gin
// not expressible in DBML: index using gin (title gin_trgm_ops)
// not expressible in DBML: index (author_id, published_at desc)
// not expressible in DBML: check (published_at is null or the author's account must still be active)
// open question: Should a slug stay reserved after unpublishing, so an old link never resolves to different writing?
// rule: Publishing sets published_at once; unpublishing clears it and frees the slug.
// rule: search_vector is derived from title and body — never written directly.
}02 / DBML boundary
Index syntax is the pressure point
The real output identifies index methods, operator classes and other source lines that DBML cannot represent directly.
The full 13-table export writes its caveats into the generated file. These examples are copied from it:
// not expressible in DBML: index using gist (path)// not expressible in DBML: check (entity_type in ('account', 'article', 'article_revision', 'comment', 'subscription', 'invoice', 'tag'))// not expressible in DBML: index using gin (search_vector)// not expressible in DBML: index using gin (title gin_trgm_ops)
source / generated DBML output