Getting started
Examples
Five real-world reference apps that demonstrate pg-flux migrations, drift detection, and codegen across Go, TypeScript, Python, and Rust.
The examples/ directory in the repository contains five standalone applications. Each one is a complete project — real schema, real migrations, generated types, and a running HTTP server — designed to show how pg-flux fits into different stacks. Every example passes pg-flux drift and pg-flux verify cleanly and runs end-to-end in CI.
Use them as reference implementations when setting up pg-flux in your own project.
#Summary
| Example | Stack | Key PG features demonstrated |
|---|---|---|
fastapi-todo |
Python + FastAPI + psycopg3 | UUID PKs, enums, RLS, Python codegen |
express-bookmarks |
TypeScript + Express + node-postgres | JSONB, tsvector, GIN indexes, DB-side trigger |
go-events |
Go + chi + pgx/v5 | IDENTITY columns, materialized view, deferrable FK, text[] GIN |
go-shop |
Go + chi + pgx/v5 | Multiple schemas, partitioned table, EXCLUDE constraint, BRIN index, INCLUDE index, domains, composite type, SECURITY DEFINER, stored procedure, grants |
rust-hrm |
Rust + Actix-web + sqlx | Everything in go-shop plus daterange, tstzrange, pg_trgm trigram GIN, window function in matview, multiple EXCLUDE constraints, self-referential table, Rust codegen |
#fastapi-todo
| Stack | Python 3.12 · FastAPI · psycopg3 · Pydantic v2 |
| PG version tested | 14 – 18 |
The canonical Python example. Demonstrates the full pg-flux Python codegen path from schema to Pydantic model to FastAPI route.
What it exercises:
- UUID primary keys (
gen_random_uuid()) and the correspondinguuid.UUIDPython mapping ENUMtype →class TodoPriority(str, Enum)generated model- Row-level security policies declared in schema and tracked by pg-flux
pg-flux gen --lang pythonproducinggen/models.pywithBaseModel,Create, andUpdatehelperspg-flux drift --strictandpg-flux verify --strictin CI
Quick start:
cd examples/fastapi-todo
docker compose up -d db
pg-flux migrate apply
pg-flux gen --lang python --out gen/
uvicorn app.main:app --reload
#express-bookmarks
| Stack | TypeScript · Express · node-postgres (pg) · Zod |
| PG version tested | 14 – 18 |
A bookmarks service that demonstrates pg-flux TypeScript codegen, full-text search via tsvector, and JSONB metadata columns.
What it exercises:
jsonbcolumn with a known shape declared via a pg-flux comment hint (tstype=...)tsvectorcolumn populated by a DB-side trigger; column type mapped tostringin TS- GIN index on
tsvectorand on a JSONB path for fast full-text and structured search pg-flux gen --lang ts --validators=zodproducingtables.ts,enums.ts, andvalidators.ts- Branded IDs (
--branded-ids) soBookmarkIdandUserIdare not interchangeable at the type level - Insert/Update helpers (
UserCreate,BookmarkCreate,BookmarkUpdate) used directly in Express route handlers
Quick start:
cd examples/express-bookmarks
docker compose up -d db
pg-flux migrate apply
pg-flux gen --lang ts --out src/db --branded-ids --insert-update-helpers --validators=zod
npm run dev
#go-events
| Stack | Go 1.25 · chi · pgx/v5 |
| PG version tested | 14 – 18 |
An event-management service that exercises several PG features that are more complex to diff and regenerate correctly: IDENTITY columns, materialized views, and deferrable foreign keys.
What it exercises:
GENERATED ALWAYS AS IDENTITYprimary keys; identity columns excluded fromInserthelpers- A materialized view (
event_stats) with a UNIQUE index for concurrent refresh; typed as a read-only Go struct - A deferrable
INITIALLY DEFERREDforeign key; pg-flux tracks deferability in the schema model text[]column with a GIN index; mapped to[]stringin Gopg-flux gen --lang go --orm-tags=sqlxwithdb:""struct tags- Multiple file layout:
tables.go,enums.go,views.go,types.go,functions.go
Quick start:
cd examples/go-events
docker compose up -d db
pg-flux migrate apply
pg-flux gen --lang go --out internal/db --orm-tags=sqlx
go run ./cmd/server
#go-shop
| Stack | Go 1.25 · chi · pgx/v5 |
| PG version tested | 14 – 18 |
The most feature-dense Go example. Uses two PG schemas (public and catalog), a range-partitioned table, and several advanced index and constraint types that are tricky to diff correctly.
What it exercises:
- Two schemas (
public,catalog) with cross-schema foreign keys; both tracked intarget_schemas - Range-partitioned
orderstable (PARTITION BY RANGE (created_at)) with child partitions declared in schema EXCLUDE USING gistconstraint on atstzrangecolumn- BRIN index on the partitioned table's timestamp column;
INCLUDEindex on a unique constraint - Domain type (
order_ref) and composite type (money_amount) both used as column types SECURITY DEFINERfunction and stored procedure; grants on schema objects declared and diffedpg-flux gen --lang go --functions— all function and procedure param types emitted--omitempty=nullableso nullable pointer fields getjson:",omitempty"tags
Quick start:
cd examples/go-shop
docker compose up -d db
pg-flux migrate apply
pg-flux gen --lang go --out internal/db --orm-tags=sqlx --functions --omitempty=nullable
go run ./cmd/server
#rust-hrm
| Stack | Rust 1.78 · Actix-web 4 · sqlx 0.8 |
| PG version tested | 14 – 18 |
A human-resources management API that is the most comprehensive example in the repository. It covers everything in go-shop and adds range types, trigram search, window functions in materialized views, and Rust codegen.
What it exercises:
daterangecolumns for employment periods;tstzrangefor shift schedulingpg_trgmextension with a GIN trigram index onemployees.namefor similarity search- A materialized view with a window function (
RANK() OVER (...)) to compute org-chart rank; typed as a read-only Rust struct with all fieldsOption<T> - Multiple
EXCLUDE USING gistconstraints; pg-flux tracks each constraint name and expression independently - Self-referential
employeestable (manager_id REFERENCES employees(id)) — nullable FK column maps toOption<i64> pg-flux gen --lang rust --functions --out gen/producing the full six-file moduletype_overrides: { numeric: rust_decimal::Decimal }for salary columns- All generated structs wired to sqlx via
#[derive(sqlx::FromRow)]and enums via#[derive(sqlx::Type)]
Quick start:
cd examples/rust-hrm
docker compose up -d db
pg-flux migrate apply
pg-flux gen --lang rust --functions --out gen/
cargo run