diff --git a/examples/aws-planetscale-drizzle-postgres/sst.config.ts b/examples/aws-planetscale-drizzle-postgres/sst.config.ts index 3128227068..6bf3679d2e 100644 --- a/examples/aws-planetscale-drizzle-postgres/sst.config.ts +++ b/examples/aws-planetscale-drizzle-postgres/sst.config.ts @@ -43,6 +43,9 @@ * bun run db:push * ``` * + * The database role sets `successor` to `postgres` so PlanetScale can reassign + * owned schema objects before deleting a non-production branch role. + * * In the function we use [Drizzle ORM](https://orm.drizzle.team) with the * [`Resource`](/docs/reference/sdk/#resource) helper. * @@ -103,6 +106,7 @@ export default $config({ "pg_write_all_data", "postgres", // Only needed for pushing schema changes ], + successor: "postgres", }); const database = new sst.Linkable("Database", { diff --git a/examples/cloudflare-hyperdrive-planetscale/sst.config.ts b/examples/cloudflare-hyperdrive-planetscale/sst.config.ts index 932b1bb737..5129bf16f8 100644 --- a/examples/cloudflare-hyperdrive-planetscale/sst.config.ts +++ b/examples/cloudflare-hyperdrive-planetscale/sst.config.ts @@ -44,6 +44,7 @@ export default $config({ inheritedRoles: ["pg_read_all_data", "pg_write_all_data"], name: `${$app.name}-${$app.stage}`, organization: db.organization, + successor: "postgres", }); const hyperdrive = new sst.cloudflare.Hyperdrive("Database", { diff --git a/www/src/content/docs/docs/planetscale.mdx b/www/src/content/docs/docs/planetscale.mdx index 16cf900c53..d821967223 100644 --- a/www/src/content/docs/docs/planetscale.mdx +++ b/www/src/content/docs/docs/planetscale.mdx @@ -50,6 +50,31 @@ const db = planetscale.getDatabaseVitessOutput({ This guide uses the Vitess resources. PlanetScale also supports Postgres with equivalent resources and functions: `PostgresBranch`, `PostgresBranchRole`, `getDatabasePostgresOutput`, and `getPostgresBranchOutput`. ::: +For branch-per-stage Postgres roles, set `successor` to another role that should +receive ownership of database objects before PlanetScale deletes the role. This +is especially important in preview and branch-per-stage workflows where +non-production roles are removed automatically after they may have created or +modified objects. + +```ts title="sst.config.ts" +const role = new planetscale.PostgresBranchRole("DatabaseRole", { + database: db.name, + organization: db.organization, + branch: branch.name, + name: `${$app.name}-${$app.stage}`, + inheritedRoles: [ + "pg_read_all_data", + "pg_write_all_data", + "postgres", // Only needed for pushing schema changes + ], + successor: "postgres", +}); +``` + +Runtime-only roles that never own database objects do not need a `successor`, +but setting one makes branch cleanup robust if the role later creates or owns +objects. + --- ## Branch per stage