fix(db): apply the retention swap migrations on Postgres 17
What & why
A fresh local setup cannot complete today. Two independent reasons, both on the path ./.superset/setup.local.sh walks.
-
db:migratestops at0122_webhook_events_swap_to_short_retention.sqlwithconstraint "webhook_events_swap_id_not_null" for table "webhook_events" does not exist, and the run rolls back, so nothing is applied. Migrations 0122 and 0125 rename the*_not_nullconstraints their swap tables get, and Postgres only catalogues not-null constraints from version 18 on. The compose file pinspostgres:17, where those constraints simply do not exist as catalogued objects, so the renames can never match. The six plus seven statements now run only when the constraint is present: identical outcome on 18, and 17 finishes with the same schema. -
Validate .envfails because.env.local.exampledoes not listSERVER_ANTHROPIC_API_KEY, one of the keysapps/api/src/env.tsrequires. That template documents itself as "the one list of keys the API requires and the placeholder each gets", so the fake placeholder now sits next to the other Anthropic one.
The alternative for the first point is moving the local image to Postgres 18, which also means mounting the volume at /var/lib/postgresql (the 18 image refuses /var/lib/postgresql/data) and rebuilding every existing local volume. Fixing the two migrations keeps the pinned version working and changes nothing where they already ran.
How I tested it
- Before: on a clean checkout,
./.superset/setup.local.shreports failedValidate .envandApply migrationssteps, andbun run db:migratestops at the rename above, leaving0rows indrizzle.__drizzle_migrations. - After: with the volume removed and
.envrecreated from the template, the same script ends withAll steps completed successfully!,128/128migrations applied, and the dev account seeded. bun drizzle-kit checkinpackages/dbreports "Everything's fine" with the edited files. The migrator only compares eachmigration.folderMillisagainst the lastcreated_atand stores the hash without ever comparing it, so editing already-applied migrations cannot affect an environment where they ran.- I had no Postgres 18 instance to run against. The 18 path is reasoned from the
pg_constraintbehaviour rather than executed: there the constraints exist, so the renames still run, unchanged.
Editing migrations 0122 and 0125
AGENTS.md forbids hand-editing packages/db/drizzle/ without explicit user confirmation, so the confirmation is recorded here: it was given on 2026-11-03, with the trade-off above in hand, to keep the guard edits rather than move the local image to Postgres 18.
What the edit is, exactly: the six *_not_null renames in 0122 and the seven in 0125 are unchanged. Each one is wrapped in a DO block that first checks pg_constraint for that name on the table the rename targets. Where the constraint is catalogued (18 and up) the rename runs as it always did; where it is not (17) it is skipped, which leaves the table with the names it already has.
Why not a follow-up migration: 0122 is what fails on a fresh 17, so the run never reaches a later file, and the migrator runs every pending file in one transaction. An environment where these two already ran does not re-run them either: drizzle picks pending migrations by folderMillis and never compares the stored hash.
No database was touched beyond the local docker compose volume setup.local.sh creates. Nothing was applied against a shared or production database, and no statement takes a lock it did not already take: the guard is a catalog read, then the same ALTER TABLE ... RENAME CONSTRAINT.
Checklist
- PR title follows conventional commits (
type(scope): subject) -
bun run lintandbun run typecheckpass (CI fails on lint warnings too) - Migrations edited with the explicit user confirmation recorded above
- "Allow edits from maintainers" is checked on fork PRs
Summary by cubic
Fixes fresh local setup on Postgres 17 by making the retention swap migrations run on the pinned v17 image and completing the required env template.
- Migrations 0122 and 0125 now rename the swap tables' not-null constraints only when Postgres catalogues them (18+); on 17 the renames are skipped with the same resulting schema.
- Each guard also checks the owning table, so a constraint with the same name on another relation can't trigger a failing rename.
.env.local.exampleadds theSERVER_ANTHROPIC_API_KEYplaceholder the API requires, fixing the failedValidate .envstep.
Summary by CodeRabbit
- Bug Fixes
- Improved reliability of database updates: they can now continue when certain optional schema adjustments are unavailable, rather than failing during the update. This helps avoid interruptions when applying changes across environments with differing database states.