|
| 1 | +--- |
| 2 | +title: Database Migrations |
| 3 | +description: Generate and review Junior schema and data migrations. |
| 4 | +type: tutorial |
| 5 | +summary: Choose the right migration type, generate it in the owning package, and verify the result. |
| 6 | +prerequisites: |
| 7 | + - /contribute/development/ |
| 8 | +related: |
| 9 | + - /cli/upgrade/ |
| 10 | + - /contribute/testing/ |
| 11 | + - /contribute/releasing/ |
| 12 | +--- |
| 13 | + |
| 14 | +Junior keeps schema and data migrations in the same ordered Drizzle journal. |
| 15 | +Each journal entry has exactly one source file: |
| 16 | + |
| 17 | +| Change | Generate | Result | |
| 18 | +| ----------------------------------------------------------------------------- | ---------------- | ----------------------------------- | |
| 19 | +| Tables, columns, indexes, or a simple SQL backfill | Schema migration | `<tag>.sql` plus a Drizzle snapshot | |
| 20 | +| Data that needs application code, state storage, Redis, or resumable progress | Data migration | `<tag>.ts` with no new snapshot | |
| 21 | + |
| 22 | +Generate the migration in the package that owns the schema. Core Junior uses |
| 23 | +`@sentry/junior`; plugin tables use their plugin package. |
| 24 | + |
| 25 | +## Generate a schema migration |
| 26 | + |
| 27 | +First change the owning Drizzle schema, such as |
| 28 | +`packages/junior/src/db/schema.ts`. Then run: |
| 29 | + |
| 30 | +```bash |
| 31 | +pnpm --filter @sentry/junior db:generate --name add_delivery_status |
| 32 | +``` |
| 33 | + |
| 34 | +For a plugin, replace the package name: |
| 35 | + |
| 36 | +```bash |
| 37 | +pnpm --filter @sentry/junior-memory db:generate --name add_memory_source |
| 38 | +``` |
| 39 | + |
| 40 | +Drizzle adds a SQL file, updates `meta/_journal.json`, and writes a schema |
| 41 | +snapshot. The generated SQL looks like: |
| 42 | + |
| 43 | +```sql title="migrations/0007_add_delivery_status.sql" |
| 44 | +ALTER TABLE "junior_conversations" |
| 45 | +ADD COLUMN "delivery_status" text; |
| 46 | +``` |
| 47 | + |
| 48 | +Review the SQL against the schema change. Prefer SQL when the work is entirely |
| 49 | +inside the same database and does not need application-level decoding. |
| 50 | + |
| 51 | +## Generate a data migration |
| 52 | + |
| 53 | +Use a data migration when SQL is not enough—for example, when moving data from |
| 54 | +state storage, preserving a Redis index, decoding an old application record, or |
| 55 | +checkpointing a long backfill. |
| 56 | + |
| 57 | +```bash |
| 58 | +pnpm --filter @sentry/junior db:generate:data --name backfill_delivery_status |
| 59 | +``` |
| 60 | + |
| 61 | +The command adds a TypeScript entry to the same journal: |
| 62 | + |
| 63 | +```ts title="migrations/0008_backfill_delivery_status.ts" |
| 64 | +import type { MigrationV1 } from "@sentry/junior-migrations"; |
| 65 | + |
| 66 | +const migration = { |
| 67 | + apiVersion: 1, |
| 68 | + async up(context) { |
| 69 | + void context; |
| 70 | + }, |
| 71 | +} satisfies MigrationV1; |
| 72 | + |
| 73 | +export default migration; |
| 74 | +``` |
| 75 | + |
| 76 | +Implement `up` with the capabilities on `context`: |
| 77 | + |
| 78 | +- `database` for queries, transactions, and database locks |
| 79 | +- `state` for Junior or plugin-scoped state |
| 80 | +- `redis` when a migration must preserve raw Redis structures |
| 81 | +- `progress` for a checkpoint that survives a failed or interrupted run |
| 82 | +- `log` for operator-facing progress messages |
| 83 | + |
| 84 | +Keep one-off decoding and transformation logic in the migration file. Do not |
| 85 | +import current Junior runtime modules from a data migration. |
| 86 | + |
| 87 | +## Review and verify |
| 88 | + |
| 89 | +Before committing: |
| 90 | + |
| 91 | +1. Confirm the new journal entry has exactly one `.sql` or `.ts` file. |
| 92 | +2. Commit the updated `meta/_journal.json`. |
| 93 | +3. Commit the new snapshot for a schema migration; a data migration should not |
| 94 | + add one. |
| 95 | +4. Do not edit, rename, reorder, or delete a migration that has shipped. |
| 96 | +5. Make long-running data migrations safe to retry and use `progress` when |
| 97 | + partial work must resume. |
| 98 | + |
| 99 | +Run the focused migration checks: |
| 100 | + |
| 101 | +```bash |
| 102 | +pnpm --filter @sentry/junior-migrations test |
| 103 | +pnpm typecheck |
| 104 | +``` |
| 105 | + |
| 106 | +`junior upgrade` runs schema and data entries in journal order. Schema-bootstrap |
| 107 | +mode is only for constructing empty test databases; it is not an upgrade path |
| 108 | +for an existing installation. |
| 109 | + |
| 110 | +## Next step |
| 111 | + |
| 112 | +Add focused coverage using the guidance in [Testing](/contribute/testing/), |
| 113 | +then review the release path in [Releasing](/contribute/releasing/). |
0 commit comments