Convert PlantUML to PostgreSQL

Generate production-ready PostgreSQL SQL code from your PlantUML diagrams in seconds.

postgres
Dialect: postgresTables: 2
Done.
plantuml

How the PlantUML to PostgreSQL conversion works

PlantUML entity diagrams are the standard in many enterprise and Java-adjacent teams, with first-class tooling in IDEs and Confluence. Entities declare mandatory fields with a leading *, and stereotypes like <<FK>> mark key columns.

Entities are `entity Name { … }` blocks — a leading `*` marks mandatory (NOT NULL) fields, `<<FK>>` marks foreign keys, and relationships use the same cardinality arrows as Mermaid (`User ||--o{ Post`). Quoted display names (`entity "User Account" as ua`) become table comments.

Paste your PlantUML source into the editor above and the engine parses it into an intermediate schema — tables, columns, relationships, indexes — then generates PostgreSQL DDL from that model. Anything the diagram syntax can't express (NOT NULL, defaults, enums, CHECK constraints, composite indexes) you add with comment directives like ' ::NN, ::DEFAULT(now()) on the line above a column. The PlantUML reference documents the full vocabulary.

What the generator emits for PostgreSQL

  • CREATE TABLE statements with double-quoted identifiers
  • SERIAL primary keys for single integer PK columns
  • CREATE TYPE … AS ENUM for ::ENUM(...) columns
  • ALTER TABLE … ADD CONSTRAINT foreign keys with ON DELETE / ON UPDATE actions
  • CREATE INDEX / CREATE UNIQUE INDEX, including partial indexes with a WHERE clause
  • COMMENT ON TABLE and COMMENT ON COLUMN for documentation carried over from the diagram

Type mapping: PlantUML to PostgreSQL

Diagram column types are logical — the generator maps each one to the idiomatic PostgreSQL type. These are the exact mappings the engine uses:

Diagram typePostgreSQL typeNotes
intINTEGERSERIAL when it is the auto-increment primary key
stringTEXTuse varchar(n) in the diagram for VARCHAR(n)
textTEXT
decimalNUMERICdecimal(10,2) passes precision through
booleanBOOLEAN
dateDATE
timestampTIMESTAMPTZtimezone-aware by default
uuidUUIDnative PostgreSQL UUID type
bigintBIGINT
blobBYTEA

Keys, relationships, and enums

A single `int id PK` column becomes `"id" SERIAL PRIMARY KEY`. Composite primary keys (e.g. on junction tables) emit a table-level `PRIMARY KEY (a, b)` clause without auto-increment.

Relationships emit `ALTER TABLE … ADD CONSTRAINT fk_<table>_<column> FOREIGN KEY … REFERENCES …` after all tables are created, so declaration order never matters. `::RELATIONSHIP[onDelete: CASCADE]` adds the corresponding ON DELETE action.

PostgreSQL gets a real enum: `::ENUM(active, inactive)` emits `CREATE TYPE status_enum AS ENUM ('active', 'inactive')` before the table, and the column uses that type. This gives you database-level validation without CHECK constraints.

Frequently asked questions

How are enums handled in the generated PostgreSQL DDL?

With native CREATE TYPE … AS ENUM statements. The enum type is created before the table that uses it, and the column references the type — not a CHECK constraint or a plain VARCHAR.

Does the converter use SERIAL or IDENTITY columns?

SERIAL. A single integer primary key becomes SERIAL PRIMARY KEY (BIGSERIAL for bigint). Columns that are both PK and FK — the one-to-one child pattern — stay plain INTEGER so the value can mirror the parent key.

Are timestamps timezone-aware?

Yes — the abstract timestamp type maps to TIMESTAMPTZ. If you need a naive timestamp, declare the column type explicitly in the diagram.

Can I add CHECK constraints and partial indexes from the diagram?

Yes. `::CHECK(price > 0)` emits an inline CHECK, and `::INDEX([email], where: "deleted_at IS NULL")` emits a partial index with a WHERE clause — both PostgreSQL-native features the converter supports directly.

Related conversions