Skip to content

Quickstart

Start from any project that has a pyproject.toml.

0. Install pgpkg

uv tool install --with 'pgpkg[diff]' pgpkg

1. Declare your project

# pyproject.toml
[tool.pgpkg]
project_name = "myext"
# prefix defaults to project_name; override if you need a different file prefix
# prefix = "myext"

2. Write your schema

Create sql/ and write files in the order they should load:

sql/
  010_schema.sql
  020_tables.sql
  030_functions.sql
  pre/
    001_roles.sql          # runs BEFORE every migration (bootstrap or step)
  post/
    999_grants.sql         # runs AFTER every migration

sql/ always represents the current, unreleased state of the database.

3. Stage a version

pgpkg stageversion 0.1.0

This writes migrations/myext--0.1.0.sql. Never edit that file by hand.

4. Keep editing sql/, then generate an incremental

pgpkg stageversion 0.2.0
pgpkg makemigration --from 0.1.0 --to 0.2.0

This spins up two temporary postgres databases (via results.temporary_local_db), loads the two staged base files into them, and writes the diff to migrations/myext--0.1.0--0.2.0.sql.

Review the diff. Edit freely; pgpkg verify will round-trip-check it later.

5. Apply to a live DB

pgpkg migrate -h localhost -d mydb -U myuser --to 0.2.0

Standard libpq environment variables (PGHOST, PGPORT, PGDATABASE, PGUSER, PGPASSWORD) are honored. You can also pass --dsn 'postgresql://...'.

6. Verify

pgpkg verify

For every incremental (a -> b) where a and b both have staged base files, this checks that loading base(a) + a→b produces the same schema as loading base(b) directly.

7. Ship

pgpkg wheel --output-dir ../myext-migrator
cd ../myext-migrator && uv build --out-dir dist

The resulting wheel ships a <project>-migrator migrate console script that bakes every staged artifact and does not need the source tree at runtime. See Wrapping into a wheel.