How to Document a PostgreSQL Schema in 2025

For the person who owns a PostgreSQL schema other people have to read, and who wants a document that survives the next schema change.

On this page

A PostgreSQL database hands you the table names and the column types, and nothing about what any of it is for. Whoever opens the schema next, including you in six months, works that out from the names alone. DbSchema's database documentation builds the missing part from the same connection you already use: a diagram of the tables and their foreign keys, and an export that carries every column, comment and index into a document you can hand to someone.

The diagram DbSchema draws from the connection

Connect DbSchema to your PostgreSQL database and it reverse-engineers the schema into an ER diagram: the tables, the columns, and a line for every foreign key. Nothing is drawn by hand and nothing is written to the database, because reverse-engineering reads the catalog and fills DbSchema's own design model with what it finds.

From there the diagram is yours to arrange. Drag the tables in DbSchema where they belong, and right-click the canvas to choose New Group when a set of them forms a module worth a box of its own. When a large schema comes back with its tables overlapping, select them all and let DbSchema place them with Diagram → Auto Arrange. One project holds as many diagrams as you want, and the same table can appear in several of them, so the orders diagram and the billing diagram each show the tables their reader cares about. All of it lives in the .dbs design file rather than in PostgreSQL, so rearranging a diagram changes nothing anyone else can see.

PostgreSQL diagram in DbSchema

HTML5 documentation you can click through

The diagram is the input to the export. Open Diagram → Export HTML5 or PDF Documentation in DbSchema and the dialog asks three things: the Format, which is HTML5, PDF or Markdown; the Diagrams to include, from the current one to all of them; and the Content, which is the schema elements that go in, such as columns, foreign keys, indexes and comments.

HTML5 is the format worth starting with. The output opens in any browser with no server behind it, and it carries the diagram as a vector image next to a searchable table list. Click a table to jump to its definition. Hover a column and the description you wrote appears as a tooltip. From a foreign key, the related table is one click away, which is the part a screenshot in a wiki page can never do.

The same dialog produces a PDF for a review that has to be printed or signed off, and Markdown for a repository or a wiki. For a PDF with Russian, Chinese or Japanese text in it, switch on Embed Unicode Font in the PDF options first, or the characters will not survive the export. Generating documentation in any of the three formats is a Pro Edition feature.

Descriptions and comment tags on tables and columns

DbSchema Database Designer

A diagram shows how the tables connect. It cannot show that one column holds a value nobody may export, or that another is kept only for a report that runs once a year. That is what the Description field of a table or a column is for in DbSchema: double-click the object in the diagram, type the sentence, and the text becomes part of the model. Every documentation format then carries it, and the HTML5 output shows it as a mouse-over tooltip on the table or column name.

Beside the free text, DbSchema attaches comment tags to any table or column: key-value pairs for the things you would otherwise keep in a spreadsheet, such as the owner of a table, a sensitivity level, or a deprecation date. Tags appear in the generated documentation and are readable from Automation Scripts, so a script that regenerates the docs on every build can act on them. Tags work on diagrams too: the export dialog can take all diagrams tagged documentation, in the order the tag value gives.

PostgreSQL has its own place for these sentences, the COMMENT ON statement, and documenting a PostgreSQL database from psql covers that route and the catalog views that read the comments back.

Descriptions in schema

The design file in Git

DbSchema keeps the whole design, tables, columns, foreign keys, diagrams and comments, in a single .dbs file in XML. Put that file in the repository next to the code it belongs to and the schema gets the history the database itself does not keep: who changed what, when, and on which branch.

DbSchema talks to the repository itself. Open the Model menu and choose Git — Collaborative Design, and the Git dialog opens on the clone, stage, commit, push and pull you would otherwise run at a terminal. After a pull, Compare with Current opens the synchronization dialog against the file that just arrived, so you see what changed in the design before deciding what to do about the database. One repository can hold several .dbs files, one per database or per component, and DbSchema opens whichever of them you need from the same Model menu. The design file and the Git dialog are in the Pro Edition.

Git integration

When the database and the model disagree

Schema changes do not always start in the design. Someone adds a table, renames a column, or drops a constraint directly in PostgreSQL, and from then on the document you exported describes a database that no longer exists.

DbSchema settles that in one dialog. Schema → Compare Model with Database lists every difference between the .dbs model and the live database, object by object: added, removed and modified tables, columns, indexes and foreign keys. For each one you choose the direction. Pull the change into the model when the database is right, or push it to the database when the design is, in which case DbSchema generates the SQL and shows it to you before anything runs. Schema synchronization is in the Pro Edition.

Because the model is a local file, none of the design work needs the database to be reachable. Keep working offline for as long as you like, and let the comparison catch up when you reconnect.

The Synchronization Dialog in DbSchema, listing each schema item, the action to apply to it, and the SQL that action generates

Views, procedures and triggers in the model

A PostgreSQL database rarely stops at tables. The logic in views, functions and triggers is exactly the part a newcomer cannot infer, and it is the part that gets left out of a hand-written document.

DbSchema reverse-engineers it along with the tables and lists it in the Project Structure panel, beside the schemas, tables, indexes and constraints. Getting there takes more than JDBC: the standard JDBC API does not expose triggers, procedures and functions, so DbSchema runs its own queries per database to read them. Their descriptions live in the model like any other object's, and the Content step of the export dialog decides which of these elements the generated documentation contains.

A view has no foreign keys of its own, which normally leaves it sitting on the diagram with no lines. Drag a column of the view onto the column it reads in a table and DbSchema draws a virtual foreign key between them, stored in the design file and never in PostgreSQL, so the diagram shows which tables the view depends on.

Views and triggers

Sample rows from the Data Generator

A schema document is easier to read when the tables are not empty. A column name and a type say little about what belongs in the column; three rows of realistic values say it at a glance, which is what a new team member or a tester wants before writing the first query.

Right-click a table header in DbSchema and choose Generate Random Data to open the Data Generator. Each column gets a pattern, from plain numbers and dates to reverse regular expressions and Groovy scripts, and DbSchema follows the foreign keys so the generated child rows point at parent rows that exist. The dialog also takes the number of rows per table, which for a document is a handful rather than a load test. The rows are inserted into the database; the patterns are saved in the .dbs file, so the next run repeats what you set up. The Data Generator is in the Pro Edition.

Sample data

Reading the data through the foreign keys

The last question a document leaves open is what the data actually looks like across the joins. DbSchema answers it in the Relational Data Editor: hold Shift+Ctrl and click a table header in the diagram, or right-click the header and choose Open in Relational Data Editor, and the rows appear.

Select a row in the parent table and DbSchema refilters every child pane to the records that match it, cascading through as many related tables as you open, with no join to write. Where the schema has no foreign key, drag one column onto another in the diagram to create a virtual foreign key: it is stored in the model file, it never touches PostgreSQL, and the editor cascades through it like a real one. The Relational Data Editor is in the Pro Edition.

Relational data view

Documentation stops being a task of its own once it comes out of the design you already keep. Download DbSchema at https://dbschema.com/download.html, connect it to your PostgreSQL database, and the diagram is there in the free Community Edition. The Pro Edition, which has a 15-day trial, adds the part you hand to other people: the HTML5, PDF and Markdown export, the .dbs design file and Git, schema synchronization, the Data Generator and the Relational Data Editor.