@prisma/orm-mongo 8.0.0-rc.7-dev.4 → 8.0.0-rc.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +8 -8
- package/skills/prisma-8/SKILL.md +5 -2
- package/skills/prisma-8/references/migration-model.md +174 -0
- package/skills/prisma-8/references/migration-review.md +6 -2
- package/skills/prisma-8/references/migrations.md +6 -3
- package/skills/prisma-8/references/quickstart.md +1 -1
- package/skills/prisma-8/upgrading/app/upgrades/8.0.0-rc.7-to-8.0.0-rc.8/instructions.md +36 -0
- package/skills/prisma-8/upgrading/extension/upgrades/8.0.0-rc.7-to-8.0.0-rc.8/instructions.md +35 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@prisma/orm-mongo",
|
|
3
|
-
"version": "8.0.0-rc.
|
|
3
|
+
"version": "8.0.0-rc.8",
|
|
4
4
|
"license": "Apache-2.0",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"sideEffects": false,
|
|
@@ -10,16 +10,16 @@
|
|
|
10
10
|
"skills"
|
|
11
11
|
],
|
|
12
12
|
"dependencies": {
|
|
13
|
-
"@prisma/orm-family-mongo": "8.0.0-rc.
|
|
14
|
-
"@prisma/orm-framework": "8.0.0-rc.
|
|
15
|
-
"@prisma/orm-target-mongo": "8.0.0-rc.
|
|
16
|
-
"@prisma/orm-toolchain": "8.0.0-rc.
|
|
13
|
+
"@prisma/orm-family-mongo": "8.0.0-rc.8",
|
|
14
|
+
"@prisma/orm-framework": "8.0.0-rc.8",
|
|
15
|
+
"@prisma/orm-target-mongo": "8.0.0-rc.8",
|
|
16
|
+
"@prisma/orm-toolchain": "8.0.0-rc.8",
|
|
17
17
|
"pathe": "^2.0.3"
|
|
18
18
|
},
|
|
19
19
|
"devDependencies": {
|
|
20
|
-
"@internal/mongo": "8.0.0-rc.
|
|
21
|
-
"@repo/tsconfig": "8.0.0-rc.
|
|
22
|
-
"@repo/tsdown": "8.0.0-rc.
|
|
20
|
+
"@internal/mongo": "8.0.0-rc.8",
|
|
21
|
+
"@repo/tsconfig": "8.0.0-rc.8",
|
|
22
|
+
"@repo/tsdown": "8.0.0-rc.8",
|
|
23
23
|
"tsdown": "0.22.14",
|
|
24
24
|
"typescript": "5.9.3"
|
|
25
25
|
},
|
package/skills/prisma-8/SKILL.md
CHANGED
|
@@ -17,7 +17,7 @@ description: >-
|
|
|
17
17
|
(schema.prisma + @prisma/client projects).
|
|
18
18
|
metadata:
|
|
19
19
|
library: '@prisma/orm-mongo'
|
|
20
|
-
library_version: '8.0.0-rc.
|
|
20
|
+
library_version: '8.0.0-rc.8'
|
|
21
21
|
---
|
|
22
22
|
|
|
23
23
|
# Prisma Next (Prisma 8)
|
|
@@ -40,6 +40,8 @@ Three steps the user does:
|
|
|
40
40
|
|
|
41
41
|
Everything else — queries, runtime wiring, build integration, debugging, feedback — sits on top of those three.
|
|
42
42
|
|
|
43
|
+
One cross-cutting migration fact: `migration plan` does **not** chain from the newest migration on disk. Its origin is `--from`, else the `db` ref, else an empty database — so a project with no ref keeps planning from scratch. Over existing migrations the CLI refuses that (`MIGRATION.PLAN_ORIGIN_UNKNOWN`) instead of writing a full-create package; choose the exit that matches your intent rather than reflexively passing `--from @empty`. [`references/migration-model.md`](references/migration-model.md) § *The trap* explains which to choose.
|
|
44
|
+
|
|
43
45
|
## Routing table
|
|
44
46
|
|
|
45
47
|
Open the reference whose triggers match the task. If more than one matches, open each — they are written to compose.
|
|
@@ -49,6 +51,7 @@ Open the reference whose triggers match the task. If more than one matches, open
|
|
|
49
51
|
| Adopt / set up / first steps | [`references/quickstart.md`](references/quickstart.md) | new project, existing database, "what can I do with Prisma Next", "where do I start", "just ran createprisma", `npx create-prisma`, first steps, first query, `prisma orm init` greenfield setup, `contract infer` + `db sign` brownfield adoption, connect-write-read first arc, day-to-day commands (`contract emit`, `db init`, `db update`, `migration plan`, `db migrate`, `db schema`, `db verify`), flags `--target` / `--authoring` / `--schema-path` / `--probe-db` / `--output` |
|
|
50
52
|
| Edit the data contract | [`references/contract.md`](references/contract.md) | schema, models, fields, attributes, relations, indexes, enums, value objects (composite types), type aliases, namespaces (Postgres schemas), cross-contract foreign keys (cross-space FK), polymorphic types (`@@discriminator` / `@@base`), extension namespaces (`pgvector.Vector(...)`, `cipherstash.EncryptedString(...)`), `prisma.config.ts` / `defineConfig`, `prisma contract emit`, PSL, `contract.prisma`, `contract.ts`, `contract.json`, `contract.d.ts`, `@internal/postgres/config`, `@internal/postgres/contract-builder`, `@internal/mongo/config`, `extensions:`, pgvector, cipherstash, postgis, paradedb, `@@control`, control policy (managed / tolerated / external / observed), soft delete, validations, callbacks |
|
|
51
53
|
| Author migrations | [`references/migrations.md`](references/migrations.md) | `db update` vs `migration plan`, `db migrate`, `migration new`, `migration show`, `db update --dry-run`, `db verify`, `db sign`, data migration, `dataTransform`, placeholder sentinels in framework-rendered `migration.ts`, `MIGRATION.HASH_MISMATCH`, PN-MIG-2001 unfilled placeholder, schema drift |
|
|
54
|
+
| Migration graph, refs, plan origin | [`references/migration-model.md`](references/migration-model.md) | migration graph, refs, `migration ref set` / `list` / `delete`, the `db` ref, `--advance-ref`, `migration plan --from`, `from: (baseline)` in plan output, greenfield / from-scratch plan, baseline, first migration before deploy (Composer / CD-managed databases), chaining migrations, retrofitting migrations onto an existing database, `MIGRATION.HASH_NOT_IN_GRAPH`, `MIGRATION.PATH_UNREACHABLE` at plan/chain time |
|
|
52
55
|
| Review migrations on deploy | [`references/migration-review.md`](references/migration-review.md) | "what migrations are going to run", "what runs on deploy / merge", merge conflict, diamond convergence, concurrent migrations, migration status, ref management for CI, staging / production environment refs, `MIGRATION.DIVERGED`, `MIGRATION.NO_MARKER`, `MIGRATION.MARKER_NOT_IN_HISTORY`, `db migrate status`, `db migrate diff`, `db migrate resolve` |
|
|
53
56
|
| Write queries | [`references/queries.md`](references/queries.md) | query, where, select, project, orderBy, limit, offset, take, skip, include, lookup, first, all, count, aggregate, groupBy, create, update, delete, upsert, returning, transaction, `db.orm`, `db.sql`, `db.query.from(...)` (Mongo pipeline), namespace-aware accessors, `.all()` Thenable, single-use iterators (`RUNTIME.ITERATOR_CONSUMED`), target-declared aggregate types (`count`, integer `sum`, and integer `avg` are `number`; `count` and integer `sum` throw outside ±(2^53 − 1) rather than round, while `avg` is a fraction already and carries no guard; `countBigInt` / `sumBigInt` / `avgDecimal` are the lossless forms, `avgDecimal` on PostgreSQL only), drizzle-style, kysely-style. Postgres/SQLite specifics: [`references/queries-postgres.md`](references/queries-postgres.md); Mongo specifics: [`references/queries-mongo.md`](references/queries-mongo.md) |
|
|
54
57
|
| Wire the runtime | [`references/runtime.md`](references/runtime.md) | `db.ts`, `postgres<Contract>(...)` / `sqlite<Contract>(...)` / `mongo<Contract>(...)` façades, middleware composition (telemetry, lints, budgets), `DATABASE_URL`, `.env`, connection pool / `poolOptions`, dev vs prod config, transactions, read replicas, multi-database, script won't exit / hangs, `db.close` / `pool.end`, `await using` / `[Symbol.asyncDispose]` |
|
|
@@ -68,7 +71,7 @@ For a vague prompt, ask **one** disambiguating question. Pick from:
|
|
|
68
71
|
- *"Are you new to Prisma Next and asking what you can do with it, or where to start?"* → [`references/quickstart.md`](references/quickstart.md) (first-touch orientation path).
|
|
69
72
|
- *"Do you want to set up a new Prisma Next project, or wire it into an existing database?"* → [`references/quickstart.md`](references/quickstart.md).
|
|
70
73
|
- *"Do you want to edit your data contract (add a model / field / relation), or work with the database (migrations, queries)?"* → [`references/contract.md`](references/contract.md) vs the others.
|
|
71
|
-
- *"Is this about authoring a migration, or about reviewing what's going to run on deploy?"* → [`references/migrations.md`](references/migrations.md) vs [`references/migration-review.md`](references/migration-review.md).
|
|
74
|
+
- *"Is this about authoring a migration, or about reviewing what's going to run on deploy?"* → [`references/migrations.md`](references/migrations.md) vs [`references/migration-review.md`](references/migration-review.md). If it's about where a plan starts, refs, or an unexpected from-scratch plan → [`references/migration-model.md`](references/migration-model.md).
|
|
72
75
|
- *"Is this about wiring Prisma Next into your build tool (Vite / Next.js / …), or about wiring `db.ts` and middleware at runtime?"* → [`references/build.md`](references/build.md) vs [`references/runtime.md`](references/runtime.md).
|
|
73
76
|
- *"What error or symptom are you seeing?"* → [`references/debug.md`](references/debug.md).
|
|
74
77
|
- *"Do you want to report this as a bug to the Prisma Next team, or is this a feature request?"* → [`references/feedback.md`](references/feedback.md).
|
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
|
|
2
|
+
# Prisma Next — The Migration Graph and Refs (Mental Model)
|
|
3
|
+
|
|
4
|
+
> **Edit your data contract. Prisma handles the rest.**
|
|
5
|
+
|
|
6
|
+
This reference teaches the model behind migration planning: what the migration graph is, what refs are, how `migration plan` chooses where to start, and the one silent mistake the model exists to prevent — a plan that starts from an empty database while migrations already exist. Hold this model and both authoring loops (dev-database loop, deploy-first loop) follow from it; skip it and the planner's defaults will eventually produce a migration you didn't intend.
|
|
7
|
+
|
|
8
|
+
## When to Use
|
|
9
|
+
|
|
10
|
+
- Deciding where the next `migration plan` should chain from.
|
|
11
|
+
- `migration plan` output shows `from: (baseline)` and you didn't expect a from-scratch plan.
|
|
12
|
+
- Setting up on-disk migrations for a project whose databases are managed by a deploy pipeline (Prisma Composer or your own CD) rather than by `db init` / `db update`.
|
|
13
|
+
- A database already exists (marked and accurate) but the repo has no on-disk migrations for it — retrofit.
|
|
14
|
+
- Questions about refs: `migration ref set` / `list` / `delete`, what the `db` ref means, `--advance-ref`, why a ref is stale.
|
|
15
|
+
|
|
16
|
+
## When Not to Use
|
|
17
|
+
|
|
18
|
+
- Filling placeholders, applying migrations, hash mismatches, drift recovery → `references/migrations.md`.
|
|
19
|
+
- What runs on deploy, environment refs in CI, concurrent-migration conflicts → `references/migration-review.md`.
|
|
20
|
+
- First-time adoption of an existing database (`contract infer` + `db sign` mechanics) → `references/quickstart.md` § *Brownfield-DB*.
|
|
21
|
+
|
|
22
|
+
## Key Concepts
|
|
23
|
+
|
|
24
|
+
### The graph is a static artifact
|
|
25
|
+
|
|
26
|
+
The on-disk migrations under `migrations/<space>/` form a directed graph. **Each migration is an edge recording a `from` and a `to` contract storage hash** (in its `migration.json`; `from: null` denotes an edge from the empty database). Nodes are the hashes those edges mention. That is the whole structure — the graph records which contract states migrations exist between, and nothing else.
|
|
27
|
+
|
|
28
|
+
Consequences worth internalising:
|
|
29
|
+
|
|
30
|
+
- **No node is privileged.** There is no "current" node, no HEAD, no special tip the planner chains from. Multiple branch tips are legal (two migrations planned off the same node). Cycles are legal (a rollback edge back to an earlier hash creates one).
|
|
31
|
+
- **The graph does not know where your database is.** "Where is my database" is answered by the database's **marker** (a live-DB record of "this database is at hash X") and, offline, by **refs**. Never by the graph.
|
|
32
|
+
- **The graph does not know where your next migration should start.** The planner has to be told an origin. That is the entire job of refs and `--from`.
|
|
33
|
+
|
|
34
|
+
### Refs — version-controlled pointers
|
|
35
|
+
|
|
36
|
+
A ref is a small committed file, `migrations/<space>/refs/<name>.json` (for your app: `migrations/app/refs/<name>.json`), containing `{ hash, invariants }`. Two roles, by convention:
|
|
37
|
+
|
|
38
|
+
- **The `db` ref** records which contract hash the project's dev database has been brought to. It is a **checkpoint, not a promise**: dev commands write it after the fact so the offline planner knows where dev iteration left off, without opening a database connection.
|
|
39
|
+
- **Environment refs** (`staging`, `production`, …) name **the contract CD will migrate that environment to** — a forward promise the repo makes, consumed at deploy time. See `references/migration-review.md` for the deploy-side workflows.
|
|
40
|
+
|
|
41
|
+
`db` is a **default name, not a magic one**. It gets no special storage, no protection; dev commands simply default to advancing a ref of that name. You can point it anywhere with `migration ref set db <hash>` and a later `db update` on the default URL will overwrite it.
|
|
42
|
+
|
|
43
|
+
Manage refs with:
|
|
44
|
+
|
|
45
|
+
```bash
|
|
46
|
+
pnpm prisma migration ref set <name> <hash-or-ref>
|
|
47
|
+
pnpm prisma migration ref list
|
|
48
|
+
pnpm prisma migration ref delete <name>
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
`migration ref set` requires the target to be the `to` hash of an on-disk migration. A hash outside the graph is refused (`MIGRATION.HASH_NOT_IN_GRAPH`); a hash that appears in the graph only as a `from` — no bundle produces it — is refused too (`MIGRATION.REF_SET_BUNDLE_NOT_FOUND`). Find node hashes with `migration list`.
|
|
52
|
+
|
|
53
|
+
### Who advances refs
|
|
54
|
+
|
|
55
|
+
| Command | Ref advancement |
|
|
56
|
+
|---|---|
|
|
57
|
+
| `db init` / `db update` (default URL) | Implicitly advance `db` (override the name with `--advance-ref <name>`; suppressed whenever `--db` is passed without `--advance-ref`, regardless of the URL — even `--db $DATABASE_URL` pointing at the default database) |
|
|
58
|
+
| `db migrate --advance-ref <name>` | The **only** apply-time advancement |
|
|
59
|
+
| plain `db migrate` | **Never advances anything** — deliberate: deploy and CI applies must not infer dev intent |
|
|
60
|
+
| `migration plan` | Never advances anything — chaining discipline is yours |
|
|
61
|
+
| deploys (Composer / CD) | Write the database's marker; structurally cannot and do not touch repo refs |
|
|
62
|
+
|
|
63
|
+
### How `migration plan` picks its origin
|
|
64
|
+
|
|
65
|
+
`migration plan` resolves its origin in exactly this order:
|
|
66
|
+
|
|
67
|
+
1. Explicit `--from <ref-name | hash | hash-prefix | migration-dir | migration-dir^ | ./path | @contract | @db | @empty>` — `@db` reads the live database's marker and is the one origin form that is not offline; `@empty` names the empty database deliberately.
|
|
68
|
+
2. No `--from` → the `db` ref (`migrations/app/refs/db.json`).
|
|
69
|
+
3. No `db` ref → **greenfield: the plan starts from the empty database.**
|
|
70
|
+
|
|
71
|
+
It is **offline** — it never consults a database, never reads a marker. Whatever the refs on disk say is what it believes. The destination defaults to the emitted `contract.json` (`--to` overrides).
|
|
72
|
+
|
|
73
|
+
The human output names the resolved origin on its `from:` line. **`from: (baseline)` means the origin resolved to nothing — the plan starts from an empty database** and will contain a create for every object in the contract.
|
|
74
|
+
|
|
75
|
+
**Auto-baseline.** When the graph is *empty* and the origin resolved through a ref to a real hash (the typical first plan after `db update` cycles), the planner emits **two** bundles in one invocation — a baseline `null → ref-hash` plus the delta `ref-hash → contract` — so the ref's hash becomes a graph node and the plan can be applied. Expect two new directories in `git status`. Details and the related refusals (`MIGRATION.HASH_NOT_IN_GRAPH`, `MIGRATION.SNAPSHOT_MISSING`) are in `references/migrations.md` § *Dev → ship transition*.
|
|
76
|
+
|
|
77
|
+
## The trap — a greenfield plan over existing migrations
|
|
78
|
+
|
|
79
|
+
**A plan whose origin is the empty contract while migrations already exist on disk is almost always a mistake.** A full-create migration cannot do what you meant: a database that has the prior migrations applied refuses it (`MIGRATION.PATH_UNREACHABLE` — no path from its marker to the new plan's destination), and running its create statements against any populated schema fails outright. The CLI refuses this at plan time: when origin resolution falls all the way through (no `--from`, no `db` ref) and migrations exist, `migration plan` stops with `MIGRATION.PLAN_ORIGIN_UNKNOWN` instead of writing the package — the error's suggestions are the three exits below; do not reflexively take the `--from @empty` one, pick by intent.
|
|
80
|
+
|
|
81
|
+
How the fall-through happens: a project that never runs `db init` / `db update` (the deploy-first path below) never acquires a `db` ref, so *every* default plan resolves to the empty origin. Running the dev loop with an explicit `--db` has the same effect: `db init` / `db update` with that flag never advance the ref, whatever URL it carries. The first time that is correct (it is the baseline; an empty migration graph plans silently); every later time it is the trap the refusal catches.
|
|
82
|
+
|
|
83
|
+
**Recognize a from-empty plan** that was produced anyway (an explicit `--from @empty`, or an older CLI without the refusal), at either layer:
|
|
84
|
+
|
|
85
|
+
- Plan output says `from: (baseline)` — while `migrations/app/` already contains migration directories.
|
|
86
|
+
- The new package's `migration.json` has `"from": null` — while sibling migrations exist.
|
|
87
|
+
- The planned operations create objects you know already exist.
|
|
88
|
+
|
|
89
|
+
**Three exits.** Pick by intent, delete the mistaken package directory first if one was written:
|
|
90
|
+
|
|
91
|
+
1. **Set a ref to the intended origin, then re-plan with the default.** Usually the last shipped migration's `to` hash: `migration list` to find it, `migration ref set db <hash>`, `migration plan --name <slug>`. Do this when you want future plans to chain without flags.
|
|
92
|
+
2. **Pass the origin explicitly:** `migration plan --from <ref-or-hash-or-migration-dir> --name <slug>`. Do this for a one-off, or when a different ref (e.g. `production`) is the honest origin.
|
|
93
|
+
3. **You genuinely mean the empty origin** — a first baseline, or a deliberate rebuild of everything. Say it explicitly: `migration plan --from @empty --name <slug>`. This is the only case where `from: (baseline)` over a non-empty directory is right, and it should be rare enough to say out loud.
|
|
94
|
+
|
|
95
|
+
## Workflow — the dev loop
|
|
96
|
+
|
|
97
|
+
The concept: while the schema is in flux, iterate the dev database with `db init` / `db update` — they apply the contract *and* keep the `db` ref current. When the shape settles, plan: the plan chains from the ref, and the auto-baseline covers the case where the graph is still empty.
|
|
98
|
+
|
|
99
|
+
```bash
|
|
100
|
+
pnpm prisma db init # once; advances the db ref
|
|
101
|
+
pnpm prisma contract emit && pnpm prisma db update # iterate; each advances the db ref
|
|
102
|
+
pnpm prisma contract emit && pnpm prisma migration plan --name <slug>
|
|
103
|
+
pnpm prisma db migrate --db $DATABASE_URL
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
After a plain `db migrate` the marker advances but the ref lags; refresh with `db update` (no-op on the DB when already current) or apply with `db migrate --advance-ref db` in the first place. Full mechanics, refusals, and recovery: `references/migrations.md` § *Dev → ship transition*.
|
|
107
|
+
|
|
108
|
+
## Workflow — the deploy-first loop (Composer / CD-managed databases)
|
|
109
|
+
|
|
110
|
+
The concept: the deploy pipeline owns the databases, so `db init` / `db update` never run and nothing ever advances a `db` ref for you. Deploys replay each database from its marker to the contract emitted at build time; they never write to `migrations/app/refs/`. Two disciplines keep this loop safe:
|
|
111
|
+
|
|
112
|
+
**Author the baseline before the first deploy.** Before anything is deployed:
|
|
113
|
+
|
|
114
|
+
```bash
|
|
115
|
+
pnpm prisma contract emit
|
|
116
|
+
pnpm prisma migration plan --name init # from: (baseline) — intended, this once
|
|
117
|
+
git add migrations/ && git commit
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
This is the one intended greenfield plan. With the baseline committed, the deployed database's marker always corresponds to a graph node, and every later state is reachable by planned migrations.
|
|
121
|
+
|
|
122
|
+
**Chain every later plan from the last shipped contract.** Nothing advances refs in this loop, so either keep the `db` ref current yourself — after each plan, `migration ref set db <new-migration-to-hash>` (the hash is a graph node as soon as the plan is written; `migration list` shows it) — or pass `--from <last-migration-dir>` on every plan. Committing the ref together with the migration keeps teammates' default plans chaining correctly too.
|
|
123
|
+
|
|
124
|
+
If you skip the chaining, the next default plan resolves to greenfield: the trap above. And note the planner accepts *any* graph-node origin without complaint — planning from a stale ref silently creates a second branch tip (legal, occasionally intended, usually not). Check `migration list` when in doubt.
|
|
125
|
+
|
|
126
|
+
## Workflow — adopt a pre-existing database
|
|
127
|
+
|
|
128
|
+
The concept: a database that predates Prisma Next enters the system by describing it, not migrating it — `contract infer` derives the contract from the live schema, and after review + `contract emit`, `db sign` records the marker. Full recipe: `references/quickstart.md` § *Brownfield-DB*.
|
|
129
|
+
|
|
130
|
+
```bash
|
|
131
|
+
pnpm prisma contract infer --db "$DATABASE_URL" --output src/prisma/contract.prisma
|
|
132
|
+
# review and re-author, then:
|
|
133
|
+
pnpm prisma contract emit
|
|
134
|
+
pnpm prisma db sign
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
After adoption the graph is still empty. Before the next schema change ships, author the baseline (deploy-first loop above) or start the dev loop — otherwise the first real plan lands in the trap.
|
|
138
|
+
|
|
139
|
+
## Workflow — retrofit a database that has no on-disk migrations
|
|
140
|
+
|
|
141
|
+
The concept: the database exists and its marker is accurate (hash **M**) — it was built by `db update` in another checkout, by a deploy pipeline, or adopted via `db sign` — but the migration graph doesn't reach M. The goal is to **make the graph reach the marker's hash**: once a baseline `null → M` exists, applying against the marked database is clean by construction — the runner starts at the marker, so the baseline never executes; only real deltas past M run.
|
|
142
|
+
|
|
143
|
+
- **It's your dev database.** Run `db update` (default URL; no-op on the DB when the contract already matches) — it advances the `db` ref and stores the contract snapshot. The next `migration plan` auto-emits the baseline plus your delta. This is just the dev loop's dev → ship transition.
|
|
144
|
+
- **It's a deployed database you must not touch.** Build the baseline offline, at the deployed contract state:
|
|
145
|
+
1. Bring the contract source back to the deployed state (check out the deployed revision of the contract file, or stash your edits), then `contract emit`.
|
|
146
|
+
2. `migration plan --name baseline` — greenfield, intended: one bundle `null → M`. Confirm its `to` matches the database (`db verify --db "$URL"` is clean at this revision).
|
|
147
|
+
3. Restore the current contract source, `contract emit`.
|
|
148
|
+
4. `migration ref set db <M>` (M is now a graph node), then `migration plan --name <slug>` — the delta `M → current`.
|
|
149
|
+
|
|
150
|
+
`db migrate` against the marked database applies only the delta.
|
|
151
|
+
|
|
152
|
+
## Common Pitfalls
|
|
153
|
+
|
|
154
|
+
1. **Assuming `migration plan` chains from the newest migration on disk.** It never does. The origin is `--from`, else the `db` ref, else empty. If neither exists, you get a from-scratch plan with no warning.
|
|
155
|
+
2. **Expecting `migration plan` or plain `db migrate` to keep the `db` ref current.** Neither touches refs. Only `db init` / `db update` advance implicitly, and only `--advance-ref` advances at apply time.
|
|
156
|
+
3. **Expecting a deploy to update refs.** Deploys write the database's marker; the files under `migrations/app/refs/` only change when you change them.
|
|
157
|
+
4. **Reading `from: (baseline)` as informational.** Over a non-empty migrations directory it is the trap announcing itself. Stop and pick an exit before applying or committing.
|
|
158
|
+
5. **`migration ref set` with a hash no on-disk migration produces.** A ref target must be the `to` hash of an on-disk migration bundle. A hash outside the graph is refused (`MIGRATION.HASH_NOT_IN_GRAPH`); a from-only graph node is refused with `MIGRATION.REF_SET_BUNDLE_NOT_FOUND`, whose fix text points at fixtures and is unhelpful here. Either way: plan the edge whose `to` is the hash first (baseline or delta), then set the ref.
|
|
159
|
+
6. **Treating `db` as reserved.** It's a naming default. Setting it yourself is fine and sometimes exactly right (deploy-first chaining, retrofit); just expect dev commands on the default URL to overwrite it.
|
|
160
|
+
7. **Authoring the first migration after the first deploy.** Then no graph node corresponds to what shipped, and every incremental path needs the retrofit. Baseline before the first deploy — it's one command.
|
|
161
|
+
|
|
162
|
+
## What Prisma Next doesn't do yet
|
|
163
|
+
|
|
164
|
+
- **No plan-time ref advancement.** `migration plan` cannot advance a ref for you; keeping the chain current is manual (`migration ref set` after each plan, or `--from` every time). If you want a plan-time advancement flag, file a feature request via the `references/feedback.md` skill.
|
|
165
|
+
|
|
166
|
+
## Checklist
|
|
167
|
+
|
|
168
|
+
- [ ] Named the intended origin before planning — a ref, a hash, or a deliberate `--from @empty`.
|
|
169
|
+
- [ ] Read the plan output's `from:` line and confirmed it names that origin — not `(baseline)` over an existing graph.
|
|
170
|
+
- [ ] In a deploy-first project: baseline authored and committed before the first deploy; every later plan chained via the `db` ref or `--from`.
|
|
171
|
+
- [ ] After each plan in a loop where nothing advances refs: advanced the `db` ref (`migration ref set db <to-hash>`) or resolved to pass `--from` next time.
|
|
172
|
+
- [ ] For a marked database with no on-disk migrations: made the graph reach the marker's hash (auto-baseline via `db update`, or an offline baseline plan) before planning deltas.
|
|
173
|
+
- [ ] Did NOT expect plain `db migrate`, `migration plan`, or a deploy to advance any ref.
|
|
174
|
+
- [ ] Did NOT apply or commit a `from: (baseline)` plan without confirming the empty origin was the intent.
|
|
@@ -35,7 +35,7 @@ A live DB is therefore the authoritative source of origin. The "recorded marker"
|
|
|
35
35
|
|
|
36
36
|
The **destination** is the contract hash you want the database to be at. Two ways to name a destination:
|
|
37
37
|
|
|
38
|
-
- **A `--to <name>`** — a named pointer to a hash, stored under `migrations/app/refs/<name
|
|
38
|
+
- **A `--to <name>`** — a named pointer to a hash, stored under `migrations/app/refs/<name>.json`. Refs are named after environments by convention (`staging`, `production`) to communicate *"this is where production is expected to be"*. The ref itself is just a hash + an optional set of required invariants; it has nothing to do with which database you connect to.
|
|
39
39
|
- **The current contract head** — implicit when no `--to` is passed. This is the hash of the current `contract.json` on disk.
|
|
40
40
|
|
|
41
41
|
`--to staging` does **not** mean "connect to the staging database." It means "navigate the database I connected to (via `--db` or config) toward whatever hash this ref points at." Database selection is orthogonal: pass `--db $STAGING_DATABASE_URL` to actually point at staging.
|
|
@@ -44,6 +44,8 @@ The **destination** is the contract hash you want the database to be at. Two way
|
|
|
44
44
|
|
|
45
45
|
The on-disk migrations form a directed graph: **nodes are contract hashes; edges are migrations.** Each migration declares a `from` hash and a `to` hash. A migration applies only when the database's current marker matches its `from` hash; running it advances the marker to its `to` hash.
|
|
46
46
|
|
|
47
|
+
The graph is a static, committed artifact. Several branch tips may coexist, rollback edges may form cycles, and no node is privileged — "where is my database" is answered by the marker and refs, never by the graph itself. `references/migration-model.md` carries the full model, including how `migration plan` chooses its origin.
|
|
48
|
+
|
|
47
49
|
`migration status` queries the graph for the path from origin to destination and reports per-edge status:
|
|
48
50
|
|
|
49
51
|
- **applied** — on the path from `EMPTY_CONTRACT_HASH` to the marker (history).
|
|
@@ -141,7 +143,9 @@ pnpm prisma migration ref list | grep production
|
|
|
141
143
|
pnpm prisma migration ref delete production
|
|
142
144
|
```
|
|
143
145
|
|
|
144
|
-
`migration ref set` writes a file at `migrations/app/refs/<name
|
|
146
|
+
`migration ref set` writes a file at `migrations/app/refs/<name>.json` carrying the hash and any required invariants. Refs are commit-friendly artifacts — keep them in git; the team agrees on what `production` points at the same way they agree on what `main` is. The hash being set must be the `to` of an on-disk migration, or the command refuses — see `references/migration-model.md` for the refusal codes.
|
|
147
|
+
|
|
148
|
+
Two ref roles, one mechanism: environment refs like `production` are the contract CD will migrate that environment to (a forward promise), while the `db` ref is a checkpoint of where the project's dev database was last brought to — written by `db init` / `db update`, consumed by `migration plan` as its default origin. `references/migration-model.md` covers the `db` ref, advancement rules, and plan-origin resolution.
|
|
145
149
|
|
|
146
150
|
## Workflow — apply a migration against an environment
|
|
147
151
|
|
|
@@ -24,13 +24,14 @@ Once the contract changes, you choose how the change reaches the database. This
|
|
|
24
24
|
## When Not to Use
|
|
25
25
|
|
|
26
26
|
- User wants to know what migrations *will run on deploy* / on merge, or to manage refs and invariants → `references/migration-review.md`.
|
|
27
|
+
- User is deciding where a plan should chain from, saw `from: (baseline)` unexpectedly, is setting up migrations for a deploy-first (Composer / CD-managed) project, or is retrofitting migrations onto an existing database → `references/migration-model.md`.
|
|
27
28
|
- User wants to edit the contract → `references/contract.md`.
|
|
28
29
|
- User wants a deeper read of a single structured error envelope → `references/debug.md`.
|
|
29
30
|
|
|
30
31
|
## Key Concepts
|
|
31
32
|
|
|
32
33
|
- **`db update` (quick path).** Reads the emitted contract, diffs against the live DB, applies the change. Optional `--dry-run` prints the plan without executing. Interactive destructive-op confirmation (or `-y` to auto-accept). **Writes no migration directory.** Operations needing data transforms are not handled by this path — `db update` excludes the `data` operation class entirely and short-circuits where a data transform would be required. Use only against a database that has no shared history with anyone else (your local dev DB).
|
|
33
|
-
- **`migration plan` (formal path).** Reads the emitted contract, diffs against the head of the
|
|
34
|
+
- **`migration plan` (formal path).** Reads the emitted contract, diffs it against a resolved origin — explicit `--from`, else the `db` ref, else the empty database; there is no "head of the graph" to chain from (see `references/migration-model.md`) — and writes a new migration package under `migrations/app/<YYYYMMDDTHHMM>_<snake_slug>/`. If any operation needs a data transform, the package's `migration.ts` contains `placeholder(...)` calls you fill in.
|
|
34
35
|
- **The `app/` segment in migration paths is the consuming application's contract-space id.** Every migration *you* author lives under `migrations/app/`. Extensions your contract depends on get their own sibling directories (`migrations/<extension-space-id>/`) — those are managed by the extension package and you don't write into them. The `app/` segment lands automatically the first time you run `migration plan` / `db init` against an app-level config.
|
|
35
36
|
- **Migration package files** (inside each `migrations/app/<dir>/`):
|
|
36
37
|
- `migration.json` — manifest (metadata + `migrationHash`).
|
|
@@ -106,7 +107,7 @@ migrations/app/refs/
|
|
|
106
107
|
└── db.json # { "hash": "<hex>", "invariants": [] }
|
|
107
108
|
```
|
|
108
109
|
|
|
109
|
-
**First `migration plan` after dev iteration.** `migration plan` defaults `--from` to the `db` ref. When the on-disk migration graph is still **empty** and the `db` ref points at a non-null hash with a store entry (typical after one or more `db update` cycles), the planner emits **two** bundles instead of one:
|
|
110
|
+
**First `migration plan` after dev iteration.** `migration plan` defaults `--from` to the `db` ref (and, when no `db` ref exists at all, falls back to planning from an empty database with no warning — over a non-empty graph that fallback is almost always a mistake; see `references/migration-model.md` § *The trap*). When the on-disk migration graph is still **empty** and the `db` ref points at a non-null hash with a store entry (typical after one or more `db update` cycles), the planner emits **two** bundles instead of one:
|
|
110
111
|
|
|
111
112
|
1. Baseline: `null → from-hash` (introduces `from-hash` as a graph node)
|
|
112
113
|
2. Delta: `from-hash → current_contract`
|
|
@@ -478,7 +479,8 @@ In non-interactive contexts (CI, `--no-interactive`, `--json`), the destructive-
|
|
|
478
479
|
6. **Aggregate `check` closure in Postgres `this.dataTransform`.** Returning `count(*)` or `bool_and(...)` breaks the precheck/postcheck contract — both sides resolve to constants. Use a rowset shape: `select('id').where(<violation>).limit(1)`.
|
|
479
480
|
7. **Two contract references in one migration.** Building a query plan against a different contract than the one passed to `this.dataTransform(endContract, ...)` raises `PN-MIG-2005`. Always import `endContract` once at module scope and use the same reference.
|
|
480
481
|
8. **Renaming and expecting the planner to detect it (Postgres).** Prisma Next has no in-contract rename hint today; the planner emits a destructive drop+add. Hand-edit `migration.ts` to rewrite the destructive op as a `rawSql({ ... })` that issues `ALTER TABLE ... RENAME COLUMN ...` (or use the two-migration keep / backfill / drop pattern), then self-emit. See `references/contract.md` § *Edit a field — rename*.
|
|
481
|
-
9. **
|
|
482
|
+
9. **Planning with no `db` ref and no `--from` in a project that already has migrations.** The origin falls through to the empty database, which would make the plan a full-create migration; `migration plan` refuses with `MIGRATION.PLAN_ORIGIN_UNKNOWN` rather than writing it. Pick the exit that matches your intent — the error lists them, and `references/migration-model.md` § *The trap* explains which to choose.
|
|
483
|
+
10. **Hand-authoring `migration.ts` from a blank file, or rewriting the rendered import line.** Migration files are framework-rendered — let `prisma migration plan` (or `migration new`) render the package, then edit only the holes the framework leaves for you. On Postgres leave the rendered `@internal/postgres/migration` (or `@internal/sqlite/migration`) import path alone; on Mongo use `@internal/family-mongo/migration` + `@internal/target-mongo/migration` as rendered. Add symbols to the existing factory import line rather than introducing new import paths.
|
|
482
484
|
|
|
483
485
|
## What Prisma Next doesn't do yet
|
|
484
486
|
|
|
@@ -508,6 +510,7 @@ The CLI collects anonymous usage data by default. To opt out, set `PRISMA_NEXT_D
|
|
|
508
510
|
|
|
509
511
|
- [ ] Contract emitted (`contract.json` + `contract.d.ts` current).
|
|
510
512
|
- [ ] Chose the right path: `db update` (local dev) vs `migration plan` + `db migrate` (anything shared).
|
|
513
|
+
- [ ] For `migration plan`: confirmed the output's `from:` line names the intended origin — not `(baseline)` over an existing graph (`references/migration-model.md`).
|
|
511
514
|
- [ ] For `migration plan`: ran `migration show` to review before `db migrate`.
|
|
512
515
|
- [ ] Filled every `placeholder(...)` in `migration.ts` (if any), built against `endContract`.
|
|
513
516
|
- [ ] `check` closures are rowset queries, not scalar aggregates.
|
|
@@ -55,7 +55,7 @@ Every application that consumes Prisma Next uses the same shape:
|
|
|
55
55
|
│ ├── contract.json
|
|
56
56
|
│ └── contract.d.ts
|
|
57
57
|
└── app/ ← created on first `migration plan` / `db init`
|
|
58
|
-
├── refs/
|
|
58
|
+
├── refs/db.json
|
|
59
59
|
└── <timestamp>_<slug>/
|
|
60
60
|
├── migration.json
|
|
61
61
|
├── ops.json
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
---
|
|
2
|
+
from: "8.0.0-rc.7"
|
|
3
|
+
to: "8.0.0-rc.8"
|
|
4
|
+
changes:
|
|
5
|
+
- id: engine-pin-moves-to-0-3-0
|
|
6
|
+
summary: |
|
|
7
|
+
The toolchain now peers `@prisma/cli-engine@0.3.0` (up from 0.2.3). Projects assembled
|
|
8
|
+
by the unified `prisma` CLI resolve the engine automatically. A project that pins
|
|
9
|
+
`@prisma/cli-engine` itself must move the pin to `0.3.0`. The engine now declares
|
|
10
|
+
`@prisma/management-api-sdk` as a peer dependency (`^1.55.0`) instead of a regular
|
|
11
|
+
dependency; the `prisma` CLI shell supplies it at runtime, so only a project that runs
|
|
12
|
+
the engine outside the CLI shell needs to install the SDK itself.
|
|
13
|
+
detection:
|
|
14
|
+
glob: "**/package.json"
|
|
15
|
+
contains:
|
|
16
|
+
- '"@prisma/cli-engine": "0.2.3"'
|
|
17
|
+
- id: contract-artifacts-restamp
|
|
18
|
+
summary: |
|
|
19
|
+
The emitted `contract.json` / `contract.d.ts` embed the toolchain version, which moves
|
|
20
|
+
to 8.0.0-rc.8. Run `contract emit` once after upgrading so the emitted artifacts match
|
|
21
|
+
the installed toolchain.
|
|
22
|
+
detection:
|
|
23
|
+
glob: "**/contract.json"
|
|
24
|
+
contains:
|
|
25
|
+
- '"version": "8.0.0-rc.7"'
|
|
26
|
+
---
|
|
27
|
+
|
|
28
|
+
# 8.0.0-rc.7 → 8.0.0-rc.8 — User upgrade instructions
|
|
29
|
+
|
|
30
|
+
## `engine-pin-moves-to-0-3-0`
|
|
31
|
+
|
|
32
|
+
For every `package.json` matched by `detection`, change the `@prisma/cli-engine` version from `0.2.3` to `0.3.0` and reinstall. If the project runs the engine outside the unified `prisma` CLI shell (rare), also install `@prisma/management-api-sdk` at a version satisfying `^1.55.0` — the engine now declares it as a peer dependency and no longer bundles it.
|
|
33
|
+
|
|
34
|
+
## `contract-artifacts-restamp`
|
|
35
|
+
|
|
36
|
+
For every `contract.json` matched by `detection`, run the project's emit command (`prisma contract emit`, or the project's `contract:emit` script) once after upgrading. The only expected diff is the embedded `version` moving to `8.0.0-rc.8`.
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
---
|
|
2
|
+
from: "8.0.0-rc.7"
|
|
3
|
+
to: "8.0.0-rc.8"
|
|
4
|
+
changes:
|
|
5
|
+
- id: engine-pin-moves-to-0-3-0
|
|
6
|
+
summary: |
|
|
7
|
+
The toolchain now peers `@prisma/cli-engine@0.3.0` (up from 0.2.3). An extension that
|
|
8
|
+
pins `@prisma/cli-engine` in its own manifests must move the pin to `0.3.0`. The engine
|
|
9
|
+
now declares `@prisma/management-api-sdk` as a peer dependency (`^1.55.0`) instead of a
|
|
10
|
+
regular dependency; the `prisma` CLI shell supplies it at runtime, so only tooling that
|
|
11
|
+
runs the engine outside the CLI shell needs to install the SDK itself.
|
|
12
|
+
detection:
|
|
13
|
+
glob: "**/package.json"
|
|
14
|
+
contains:
|
|
15
|
+
- '"@prisma/cli-engine": "0.2.3"'
|
|
16
|
+
- id: contract-space-restamp
|
|
17
|
+
summary: |
|
|
18
|
+
The emitted `contract.json` / `contract.d.ts` embed the toolchain version, which moves
|
|
19
|
+
to 8.0.0-rc.8. Rebuild the extension's contract space (the package's `build:contract-space`
|
|
20
|
+
script) once after upgrading so the emitted artifacts match the installed toolchain.
|
|
21
|
+
detection:
|
|
22
|
+
glob: "**/contract.json"
|
|
23
|
+
contains:
|
|
24
|
+
- '"version": "8.0.0-rc.7"'
|
|
25
|
+
---
|
|
26
|
+
|
|
27
|
+
# 8.0.0-rc.7 → 8.0.0-rc.8 — Extension author upgrade instructions
|
|
28
|
+
|
|
29
|
+
## `engine-pin-moves-to-0-3-0`
|
|
30
|
+
|
|
31
|
+
For every `package.json` matched by `detection`, change the `@prisma/cli-engine` version from `0.2.3` to `0.3.0` and reinstall. If the extension's tooling runs the engine outside the unified `prisma` CLI shell (rare), also install `@prisma/management-api-sdk` at a version satisfying `^1.55.0` — the engine now declares it as a peer dependency and no longer bundles it.
|
|
32
|
+
|
|
33
|
+
## `contract-space-restamp`
|
|
34
|
+
|
|
35
|
+
For every `contract.json` matched by `detection`, run the extension package's `build:contract-space` script (or its emit command) once after upgrading. The only expected diff is the embedded `version` moving to `8.0.0-rc.8`.
|