DEV Community

Cover image for How to Visualize a PostgreSQL Schema: 5 Ways Compared
Varun Krishnan
Varun Krishnan

Posted on

How to Visualize a PostgreSQL Schema: 5 Ways Compared

The short version

Your Postgres schema is perfectly readable to the database and almost unreadable to a human. The tables, columns, and foreign keys you need are spread across pg_catalog, information_schema, and a few hundred lines of migration SQL. Visualization means collapsing all of that into a picture you can actually reason about.

There are five practical ways to get there. They are not equivalent. Each makes a different trade between speed, depth, and how current the diagram stays.

The five ways at a glance

Method Setup Interactive Stays current Best for
psql + pg_catalog Zero No Always (it's live) Quick inspection
IDE built-ins (pgAdmin, DBeaver) Already installed Partly Snapshot, manual re-run One-off look
Manual diagramming (draw.io, dbdiagram.io) Short Yes Drifts (you maintain it) Designing a new schema
Migrations → DDL (Prisma, Rails) Medium No Re-run on change Documenting from code
Live connection string (dbdiagramr) None (paste URL) Yes Regenerate in 10 seconds Understanding a real DB

1. psql and pg_catalog: the baseline

The fastest text-only view is psql. \dt lists all tables, \d table_name shows one table's structure including its foreign keys. To see every relationship in one shot, query information_schema directly:

SELECT tc.table_name,
       kcu.column_name,
       ccu.table_name AS foreign_table_name,
       ccu.column_name AS foreign_column_name
FROM information_schema.table_constraints tc
JOIN information_schema.key_column_usage kcu
  ON tc.constraint_name = kcu.constraint_name
JOIN information_schema.constraint_column_usage ccu
  ON ccu.constraint_name = tc.constraint_name
WHERE tc.constraint_type = 'FOREIGN KEY'
  AND tc.table_schema = 'public';
Enter fullscreen mode Exit fullscreen mode

Precise and always available. But it's a list, not a picture. Past a dozen tables you're reconstructing the graph in your head, which is exactly what visualization is supposed to remove.

2. IDE built-ins: pgAdmin, DBeaver, DataGrip

If you already have a GUI client, it probably ships with an ER diagram generator:

  • pgAdmin 4: right-click the database → ERD For Database. Free, already installed. Auto-layout struggles past a few dozen tables, and it regenerates by hand.
  • DBeaver (Community is enough): open the ER Diagram tab. Genuinely free, cross-platform, exports PNG/SVG.
  • DataGrip: Diagrams → Show Visualization. The best-feeling interactive diagram of the three; paid, single-user.

The honest limitation they all share: any IDE-based diagram is a snapshot. Nothing to share but an exported image, and it drifts the moment someone runs a migration.

3. Manual diagramming: draw.io, dbdiagram.io, DrawSQL

The classic approach, and great for designing a schema you haven't built yet. dbdiagram.io and DrawSQL are excellent editors. You write DBML or drag tables, and get a clean diagram you can export, share, and version.

The catch is drift. The diagram is a hand-made copy of the schema at one moment in time. The day someone adds a column or a foreign key, the diagram is wrong. A wrong diagram is worse than none, because people trust it. Building it from scratch takes 30 minutes to an hour, and it's stale the moment a migration lands.

Use these when you're designing. They struggle to document a real schema over time.

4. Generate from your migrations

If your schema lives in migration files (Prisma, Drizzle, Rails, Flyway), you can derive the structure from code instead of a live connection:

# Dump structure only, never row data
pg_dump --schema-only mydb > schema.sql
Enter fullscreen mode Exit fullscreen mode

Then feed the DDL to any SQL-to-diagram tool. This is the right path when you can't or don't want to expose credentials. The trade-off: it documents the migrations, not necessarily what's actually deployed. Regenerating on every change is automation you have to build and maintain.

5. Paste a live connection string: the "always current in 10 seconds" option

The approach that solves both accuracy and effort: point a tool at the real database and let it introspect the schema itself. No schema code, no hand-arranging, nothing to keep in sync. The diagram is what's in your database right now.

That's exactly what dbdiagramr does. You paste a PostgreSQL connection string into it and it:

  1. Connects and reads the schema, structure only, never your row data
  2. Queries information_schema for tables, columns, primary keys, and foreign keys
  3. Renders an interactive ER diagram you can pan, zoom, drag tables around, and hover over to trace relationships
  4. Exports as SVG or PNG

Because it introspects the live database, there's no drift to manage. Change a migration, paste the same string again, and you have an up-to-date diagram in under 10 seconds. Your connection string is never stored. It's introspected and discarded immediately.

Not sure what an ER diagram even looks like yet? The schema library has live diagrams of the Supabase auth, NextAuth.js, Laravel, and Django schemas you can pan and zoom before you connect your own database.

Why you should care about "stays current"

Every method above the last one shares the same failure mode: the diagram is a snapshot, and keeping it current is your problem. Walk into any team that's been around a while and you'll find a "schema diagram" in a wiki from eight months ago. A wrong diagram is worse than none. It's confidently wrong.

The test that settles it: how much work does it take to make this picture true again? If the answer is "re-export from my IDE" or "drag the boxes by hand one more time," the humans will stop doing it and the diagram will lie to you.

FAQ

What's the easiest way to generate an ER diagram from a Postgres database?
If you have a GUI client open, it's a built-in feature. pgAdmin's ERD For Database, DBeaver's ER Diagram tab, or DataGrip's visualization all generate one in a couple of clicks. For a shareable diagram that matches your database as it is right now, a live-introspection tool is fastest because there's nothing to maintain.

Can I create a Postgres ERD without connecting to the live database?
Yes. Run pg_dump --schema-only and feed the DDL to a SQL-to-diagram tool, or parse your migration files. That's the safer path when you can't or don't want to expose production credentials.

How do I keep a schema diagram up to date?
Manual tools require manual regeneration, so in practice they drift. The reliable fix is introspection: regenerate straight from the live database (a paste of the connection string) or wire documentation generation into CI.

Does pgAdmin make ER diagrams?
Yes. pgAdmin 4 includes an ERD tool. Right-click the database → ERD For Database, or Tools → ERD Tool. Free and built in, though the auto-layout is best on small-to-medium schemas.

How to choose

  • Just want a quick look? psql or your IDE's built-in diagram. Fast, local, gone tomorrow, which is fine.
  • Designing a new schema? draw.io, dbdiagram.io, or DrawSQL are the right tools for the job.
  • Need to understand a database that already exists, or document one that keeps changing? Introspect the live schema. That's the perspective that actually survives contact with real databases.

Try It

Live: https://dbdiagramr.space

GitHub: https://github.com/VarunKvK/dbdiagramr

If this is useful to you, a GitHub star helps a solo dev keep building in public. I got tired of hand-drawing diagrams that went stale. Figured others did too.

Top comments (0)