diff --git a/.github/workflows/docs-prose.yml b/.github/workflows/docs-prose.yml index ebfa2adab3..e2aaf435be 100644 --- a/.github/workflows/docs-prose.yml +++ b/.github/workflows/docs-prose.yml @@ -2,7 +2,7 @@ name: Docs Prose # Runs the AI-signs prose checker from .claude/skills/docs-reader-review over # every docs page a pull request adds or changes. The generated error-reference -# pages are skipped: their text comes from prisma/prisma and prisma/prisma-cli, +# pages are skipped: their text comes from prisma/orm and prisma/prisma-cli, # so the fix for a hit there is upstream. on: diff --git a/.github/workflows/error-reference-check.yml b/.github/workflows/error-reference-check.yml index a79b5179d9..f1bf864988 100644 --- a/.github/workflows/error-reference-check.yml +++ b/.github/workflows/error-reference-check.yml @@ -1,7 +1,7 @@ name: Error Reference Check # The published error-reference pages must list every structured error code -# the products can emit — prisma/prisma (main) errors link to +# the products can emit — prisma/orm (main) errors link to # /docs/orm/reference/error-reference#, prisma/prisma-cli (main) errors # to /docs/cli/error-reference#. This check fails if any known code is # missing from its page, even if the sync workflow breaks. @@ -37,10 +37,10 @@ jobs: with: persist-credentials: false - - name: Checkout prisma/prisma (main) + - name: Checkout prisma/orm (main) uses: actions/checkout@v4 with: - repository: prisma/prisma + repository: prisma/orm ref: main path: prisma-src persist-credentials: false diff --git a/.github/workflows/sync-error-reference-docs.yml b/.github/workflows/sync-error-reference-docs.yml index 8fb07dbf23..7bb38980ad 100644 --- a/.github/workflows/sync-error-reference-docs.yml +++ b/.github/workflows/sync-error-reference-docs.yml @@ -24,10 +24,10 @@ jobs: with: persist-credentials: false - - name: Checkout prisma/prisma (main) + - name: Checkout prisma/orm (main) uses: actions/checkout@v4 with: - repository: prisma/prisma + repository: prisma/orm ref: main path: prisma-src persist-credentials: false diff --git a/apps/docs/content/docs/(index)/prisma-orm/from-scratch.mdx b/apps/docs/content/docs/(index)/prisma-orm/from-scratch.mdx index b15f20ad57..d10ae617ac 100644 --- a/apps/docs/content/docs/(index)/prisma-orm/from-scratch.mdx +++ b/apps/docs/content/docs/(index)/prisma-orm/from-scratch.mdx @@ -128,6 +128,8 @@ App space ✔ Advanced ref "db" → b5ae4e66fad1f0b7dd5590568f75a12a6f4576e9f367a787a69a4e729abac1fb ``` +`1 contract space` and `App space` in the output both refer to the migration history for your own models, which is in `migrations/app/` and is called the `app` [contract space](/orm/migrations/the-migration-graph#terms-used-on-this-page). + The `marker` line in the output is the record that signing stores in the database: the hash that identifies the version of the contract the database now matches. `db init` also writes `migrations/app/refs/db.json`, called the `db` ref: a file that records which contract version your development database is at, so that `migration plan` in step 6 knows where to start. The `Advanced ref "db"` line in the output is `db init` writing it. Commit it, together with the snapshot of the contract that `db init` writes under `migrations/snapshots/`. If the command fails with `DRIVER.CONNECTION_FAILED`, `DATABASE_URL` in `.env` is wrong or the database is not reachable. A `SECURITY WARNING` about SSL modes comes from the `pg` driver and does not stop the command; change `sslmode=require` to `sslmode=verify-full` in `.env` to silence it. ## 5. Write and read data diff --git a/apps/docs/content/docs/(index)/prisma-orm/quickstart/mongodb.mdx b/apps/docs/content/docs/(index)/prisma-orm/quickstart/mongodb.mdx index 81089232c7..a267222968 100644 --- a/apps/docs/content/docs/(index)/prisma-orm/quickstart/mongodb.mdx +++ b/apps/docs/content/docs/(index)/prisma-orm/quickstart/mongodb.mdx @@ -65,6 +65,8 @@ npm run migrate The output ends with a summary like `Applied 3 operation(s) across 1 contract space`. If it fails with a connection error, confirm `MONGODB_URL` is exported in this shell and points at a running MongoDB deployment; if the string still names `replicaSet=rs0`, that replica set has to exist. +The `1 contract space` in the summary is the migration history for your own models. Prisma ORM calls it the `app` [contract space](/orm/migrations/the-migration-graph#terms-used-on-this-page), and its migrations are in `migrations/app/`. + ## 4. Run the app Start the app and confirm the sample query runs successfully. diff --git a/apps/docs/content/docs/cli/db-migrate.mdx b/apps/docs/content/docs/cli/db-migrate.mdx index 2995992bac..be9af296f0 100644 --- a/apps/docs/content/docs/cli/db-migrate.mdx +++ b/apps/docs/content/docs/cli/db-migrate.mdx @@ -6,7 +6,9 @@ metaTitle: db migrate | Prisma ORM CLI metaDescription: Learn how to apply pending Prisma ORM on-disk migrations with the db migrate command. --- -`db migrate` applies pending on-disk migrations to advance the database. It walks every contract space (app and extensions) and applies migrations in canonical order: extensions alphabetically, then the app. It applies only the migrations that exist on disk and never generates new operations. +`db migrate` applies pending on-disk migrations to advance the database. It walks every contract space and applies migrations in canonical order: extensions alphabetically, then the app. It applies only the migrations that exist on disk and never generates new operations. + +Prisma ORM keeps one migration history for your own models, called the `app` space, in `migrations/app/`, and one for each [extension package](/orm/extensions/using-extensions) that ships its own migrations, such as pgvector. Each of these histories is a [contract space](/orm/migrations/the-migration-graph#terms-used-on-this-page). Use it from a controlled deployment step after reviewing migration packages. @@ -21,13 +23,19 @@ npx prisma db migrate --db "$DATABASE_URL" | Option | What it does | | --- | --- | | `--db ` | Connects to the database. | -| `--to ` | Applies migrations up to a target contract (hash, prefix, ref name, migration directory name, `^`, or `./path`). | +| `--to ` | Applies migrations up to a target contract state. Accepts a [contract reference](/orm/migrations/the-migration-graph#contract-reference-forms): a hash, a hash prefix, a [ref name](#contract-references), a migration directory name, or [`^`](#contract-references). With `--show`, it also accepts the tokens [`@contract`](#contract-references) and [`@empty`](#contract-references). | | `--advance-ref ` | Advances the named [ref](/cli/migration-ref) to the post-apply marker after success. | | `--show` | Previews the migration route without applying (read-only). | -| `--from ` | Sets the from-state for the `--show` preview: `@contract` (the emitted contract), `@db` (the database's current marker), a hash, a ref name, or a migration directory. | +| `--from ` | Use it with `--show`, where it sets the starting state for the preview. Accepts a [contract reference](/orm/migrations/the-migration-graph#contract-reference-forms): a hash, a hash prefix, a [ref name](#contract-references), a migration directory name, [`^`](#contract-references), [`@contract`](#contract-references), [`@db`](#contract-references), or [`@empty`](#contract-references). | | `--config ` | Read this config file instead of `./prisma.config.ts`. | | `--json` | Prints a machine-readable result. | +### Contract references [#contract-references] + +A ref name is a name you gave a contract state with [`migration ref set`](/cli/migration-ref), such as `prod`. `^` is a migration directory name followed by `^`, and it names the contract state before that migration, while the directory name alone names the state after it. [Contract references each command accepts](/orm/migrations/the-migration-graph#contract-reference-forms) lists the forms for every command. + +`@contract` names the contract in `contract.json`, which `contract emit` writes. The database stores a marker, a row that says which contract state it matches. `@db` names that state. `@empty` names the empty database, before any migration. + ## Recommended flow ```npm diff --git a/apps/docs/content/docs/cli/db-sign.mdx b/apps/docs/content/docs/cli/db-sign.mdx index 8ab9514963..50350a5de8 100644 --- a/apps/docs/content/docs/cli/db-sign.mdx +++ b/apps/docs/content/docs/cli/db-sign.mdx @@ -8,7 +8,7 @@ metaDescription: Learn how to sign a database once it matches the current Prisma `db sign` verifies that the live database satisfies the emitted contract and, if so, writes or updates the database signature. The signature records that this database instance matches a specific contract version. -It is idempotent and safe to run in CI or a deployment pipeline. Use it after importing or inferring an existing schema, or after a deployment flow that already applied the required database changes. +It is safe to run more than once, and safe to run in CI or a deployment pipeline. Use it after importing or inferring an existing schema, or after a deployment flow that already applied the required database changes. After a successful signature, `db sign` also stores the signed contract as a snapshot and points the [ref](/cli/migration-ref) named `db` at it, so the next [`migration plan`](/cli/migration-plan) starts from the state you just signed instead of from an empty database. Unlike `db init` and `db update`, passing `--db` does not turn this off, because you normally sign the real database. Pass `--no-advance-ref` when you do not want the command to write a ref or a snapshot, for example in a deployment pipeline. @@ -22,14 +22,18 @@ npx prisma db sign --db "$DATABASE_URL" | Argument or option | What it does | | --- | --- | -| `[contract]` | Signs against a specific contract reference (hash, prefix, ref name, or migration directory name) instead of the emitted contract. | +| `[contract]` | Signs against a specific contract state instead of the emitted contract. Accepts a [contract reference](/orm/migrations/the-migration-graph#contract-reference-forms): a hash, a hash prefix, a [ref name](#contract-references), a migration directory name, or [`^`](#contract-references). | | `--db ` | Connects to the database. | -| `--contract ` | The contract reference as a flag. Also accepts the `^` and `./path` forms that the positional argument does not. | +| `--contract ` | The same value as `[contract]`, passed as an option in place of the argument. | | `--advance-ref ` | Advances this ref instead of `db` after a successful signature. | | `--no-advance-ref` | Signs without writing any ref or snapshot. Cannot be combined with `--advance-ref`. | | `--config ` | Read this config file instead of `./prisma.config.ts`. | | `--json` | Prints a machine-readable result. It includes `advancedRef` with the ref name and contract hash, or `null` when no ref was written. | +### Contract references [#contract-references] + +A ref name is a name you gave a contract state with [`migration ref set`](/cli/migration-ref), such as `prod`. `^` is a migration directory name followed by `^`, and it names the contract state before that migration, while the directory name alone names the state after it. [Contract references each command accepts](/orm/migrations/the-migration-graph#contract-reference-forms) lists the forms for every command. + ## Exit codes | Code | Meaning | @@ -61,7 +65,7 @@ The plan starts from the signed contract, so it contains only the change you mad Use `db sign` only after you believe the live database already matches the emitted contract. It is common after: -- `contract infer` for a brownfield database +- `contract infer` for an existing database - a manually reviewed migration flow - a database restore that you need to mark as matching the current contract diff --git a/apps/docs/content/docs/cli/db-update.mdx b/apps/docs/content/docs/cli/db-update.mdx index 92cffc299a..9eb34c949f 100644 --- a/apps/docs/content/docs/cli/db-update.mdx +++ b/apps/docs/content/docs/cli/db-update.mdx @@ -22,11 +22,15 @@ npx prisma db update --db "$DATABASE_URL" | --- | --- | | `--db ` | Connects to the database. | | `--dry-run` | Shows planned operations without applying them. | -| `--to ` | Updates to a specific contract (hash, prefix, ref name, migration directory name, or `./path`). | +| `--to ` | Updates to a specific contract state. Accepts a [contract reference](/orm/migrations/the-migration-graph#contract-reference-forms): a hash, a hash prefix, a [ref name](#contract-references), a migration directory name, or [`^`](#contract-references). | | `--advance-ref ` | Advances the named [ref](/cli/migration-ref) to the post-command contract hash. Without it, `db update` advances `db` when `--db` is omitted, and advances nothing when `--db` is passed. | | `--config ` | Read this config file instead of `./prisma.config.ts`. | | `--json` | Prints a machine-readable result. | +### Contract references [#contract-references] + +A ref name is a name you gave a contract state with [`migration ref set`](/cli/migration-ref), such as `prod`. `^` is a migration directory name followed by `^`, and it names the contract state before that migration, while the directory name alone names the state after it. [Contract references each command accepts](/orm/migrations/the-migration-graph#contract-reference-forms) lists the forms for every command. + ## How the db ref moves Run without `--db`, `db update` takes the connection from `db.connection` in `prisma.config.ts` and advances the [ref](/cli/migration-ref) named `db` to the contract it just applied. Pass `--db` and that advancement is suppressed, even when the URL is the same one the config holds. Pass `--advance-ref db` alongside `--db` to get it back. diff --git a/apps/docs/content/docs/cli/index.mdx b/apps/docs/content/docs/cli/index.mdx index 49fc3c948b..8372b126e5 100644 --- a/apps/docs/content/docs/cli/index.mdx +++ b/apps/docs/content/docs/cli/index.mdx @@ -33,7 +33,7 @@ The platform commands manage the services, databases, and buckets your app runs ## Common workflows -There are two main entry points. Platform users deploy apps, create databases, and provision buckets with the [platform commands](#platform-commands). ORM users manage their schema, contracts, and migrations with the ORM and migration commands. +Platform users deploy apps, create databases, and provision buckets with the [platform commands](#platform-commands), while ORM users manage their schema, contracts, and migrations with the ORM and migration commands. ### Deploy an app @@ -111,7 +111,7 @@ npx prisma skills sync ## Other commands -A few commands ship without dedicated pages yet. `contract format` formats your PSL contract source in place, including a Prisma ORM 7 schema read through `prisma7Schema`, and `lsp` starts the Prisma ORM language server (spawned by editors, not run interactively; see [Editor support](/orm/contract-authoring/editor-support)). The `migration` group also has read-only inspection commands: `migration list` (on-disk migrations per contract space; `--space`, `--ascii`, `--legend`), `migration log` (executed history from the database ledger; `--db`, `--utc`, `--ascii`), `migration graph` (graph topology; `--space`, `--dot` for Graphviz output, `--ascii`, `--legend`), and `migration check [target]` (artifact and graph integrity; `--space`). Run any of them with `--help` for the details. +A few commands ship without dedicated pages yet. `contract format` formats your PSL contract source in place, including a Prisma ORM 7 schema read through `prisma7Schema`, and `lsp` starts the Prisma ORM language server (spawned by editors, not run interactively; see [Editor support](/orm/contract-authoring/editor-support)). The `migration` group also has read-only inspection commands: `migration list` (on-disk migrations per [contract space](/orm/migrations/the-migration-graph#terms-used-on-this-page); `--space`, `--ascii`, `--legend`), `migration log` (executed history from the database ledger; `--db`, `--utc`, `--ascii`), `migration graph` (the chain of migrations; `--space`, `--dot` for Graphviz output, `--ascii`, `--legend`), and `migration check [target]` (artifact and graph integrity; `--space`). Run any of them with `--help` for the details. ## Global flags diff --git a/apps/docs/content/docs/cli/migration-new.mdx b/apps/docs/content/docs/cli/migration-new.mdx index 72826fdadb..f8784eee0b 100644 --- a/apps/docs/content/docs/cli/migration-new.mdx +++ b/apps/docs/content/docs/cli/migration-new.mdx @@ -25,7 +25,7 @@ npx prisma migration new --name split-name | `--config ` | Read this config file instead of `./prisma.config.ts`. | | `--json` | Prints a machine-readable result. | -`migration new --from` takes only a hash or a unique prefix of one. Unlike [`migration plan --from`](/cli/migration-plan#options), it does not accept a migration directory name or a ref name. It refuses `--from` when `migrations/app/` has no migrations, and refuses a prefix that matches more than one migration. Run `npx prisma migration list` to see the hashes of your migrations. +`migration new --from` takes only a hash or a unique prefix of one. Unlike [`migration plan --from`](/cli/migration-plan#options), it does not accept a migration directory name or a ref name. It refuses `--from` when `migrations/app/` has no migrations, and refuses a prefix that matches more than one migration. Run `npx prisma migration list` to see the hashes of your migrations. [Contract references each command accepts](/orm/migrations/the-migration-graph#contract-reference-forms) compares it with the other commands. ## Where it starts diff --git a/apps/docs/content/docs/cli/migration-plan.mdx b/apps/docs/content/docs/cli/migration-plan.mdx index ac181bd963..f512dbd4e6 100644 --- a/apps/docs/content/docs/cli/migration-plan.mdx +++ b/apps/docs/content/docs/cli/migration-plan.mdx @@ -27,7 +27,7 @@ The baseline only creates things, because it is planned from an empty database, If a migration already starts from the contract the `db` ref points at, `migration plan` writes a second migration that starts from the same contract, so the [migration history](/orm/migrations/the-migration-graph) splits into two branches. This happens, for example, after `db migrate` without `--advance-ref db`, which applies migrations but leaves the `db` ref where it was. `migration plan` still writes the migration and prints a warning. A database that has already run the existing migration then has no migration leading to your new contract, so `db migrate` on that database fails with `MIGRATION.PATH_UNREACHABLE`. To build on the newest migration instead, delete the directory this run wrote and plan again with `--from` set to the newest migration's directory name. -The command is offline. It does not need a database connection. +The command is offline, so it does not need a database connection. ## Usage @@ -40,11 +40,15 @@ npx prisma migration plan --name add_users_table | Option | What it does | | --- | --- | | `--name ` | Sets the migration directory name suffix. | -| `--from ` | Uses a specific starting contract reference (hash, prefix, ref name, migration directory name, `^`, `./path`, or `@empty`) instead of the `db` ref. `migration plan` is offline, so `@db` and `@contract` are not accepted here. | -| `--to ` | Sets the destination contract reference. Defaults to the emitted contract. Same grammar as `--from`, except that `@empty` is refused as a destination. | +| `--from ` | Uses a specific starting contract state instead of the `db` ref. Accepts a [contract reference](/orm/migrations/the-migration-graph#contract-reference-forms): a hash, a hash prefix, a [ref name](#contract-references), a migration directory name, [`^`](#contract-references), or [`@empty`](#contract-references). `@db` is not accepted here, because `migration plan` is offline and cannot read a database. `@contract` is not accepted either. | +| `--to ` | Sets the destination contract state. Defaults to the emitted contract. Accepts the same forms as `--from`, except `@empty`, which is refused as a destination. | | `--config ` | Read this config file instead of `./prisma.config.ts`. | | `--json` | Prints a machine-readable result. | +### Contract references [#contract-references] + +A ref name is a name you gave a contract state with [`migration ref set`](/cli/migration-ref), such as `prod`. `^` is a migration directory name followed by `^`, and it names the contract state before that migration, while the directory name alone names the state after it. `@empty` names the empty database, before any migration. [Contract references each command accepts](/orm/migrations/the-migration-graph#contract-reference-forms) lists the forms for every command. + ## Recommended flow ```npm diff --git a/apps/docs/content/docs/cli/migration-ref.mdx b/apps/docs/content/docs/cli/migration-ref.mdx index 8931ff9679..0c15cfafea 100644 --- a/apps/docs/content/docs/cli/migration-ref.mdx +++ b/apps/docs/content/docs/cli/migration-ref.mdx @@ -34,7 +34,7 @@ npx prisma migration ref delete production | Subcommand | What it does | | --- | --- | -| `set ` | Points a ref at a contract. The contract is a hash or prefix, another ref name, a migration directory name, or `^` for that migration's source contract. | +| `set ` | Points a ref at a contract. The contract is a [contract reference](/orm/migrations/the-migration-graph#contract-reference-forms): a hash or prefix, another ref name, a migration directory name, or `^` for that migration's source contract. | | `list` | Lists every ref with the contract hash it points at and the invariants recorded against it. | | `delete ` | Deletes a ref. The contract it pointed at is untouched. | diff --git a/apps/docs/content/docs/cli/migration-status.mdx b/apps/docs/content/docs/cli/migration-status.mdx index 816a4f6b8b..166d305c63 100644 --- a/apps/docs/content/docs/cli/migration-status.mdx +++ b/apps/docs/content/docs/cli/migration-status.mdx @@ -21,14 +21,22 @@ npx prisma migration status --db "$DATABASE_URL" | Option | What it does | | --- | --- | | `--db ` | Connects to the database. | -| `--space ` | Narrows output to a single contract space. | -| `--to ` | Sets the target contract reference (hash, prefix, ref name, migration directory name, `^`, or `./path`). | -| `--from ` | Sets the origin contract reference. With `--from`, the command computes the path offline and does not need a database. | -| `--legend` | Prints a key for the tree glyphs and lane colors. | +| `--space ` | Narrows output to a single [contract space](#contract-spaces), named by its directory under `migrations/`. | +| `--to ` | Sets the target contract state. Accepts a [contract reference](/orm/migrations/the-migration-graph#contract-reference-forms): a hash, a hash prefix, a [ref name](#contract-references), a migration directory name, [`^`](#contract-references), or [`@empty`](#contract-references). | +| `--from ` | Sets the origin contract state, and accepts the same forms as `--to`. With `--from`, the command computes the path offline and does not need a database. | +| `--legend` | Prints a key to the symbols in the rows (`○`, the arrows, `✓`, `⧗`, `∅`) and to the labels. | | `--ascii` | Uses ASCII glyphs (pipe-friendly). | | `--config ` | Read this config file instead of `./prisma.config.ts`. | | `--json` | Prints a machine-readable result. | +### Contract spaces [#contract-spaces] + +Prisma ORM keeps one migration history for your own models, called the `app` space, in `migrations/app/`, and one for each [extension package](/orm/extensions/using-extensions) that ships its own migrations, such as pgvector. Each of these histories is a [contract space](/orm/migrations/the-migration-graph#terms-used-on-this-page). Pass `--space app` to see only your own migrations. + +### Contract references [#contract-references] + +A ref name is a name you gave a contract state with [`migration ref set`](/cli/migration-ref), such as `prod`. `^` is a migration directory name followed by `^`, and it names the contract state before that migration, while the directory name alone names the state after it. `@empty` names the empty database, before any migration. [Contract references each command accepts](/orm/migrations/the-migration-graph#contract-reference-forms) lists the forms for every command. + ## Examples ```npm @@ -40,8 +48,35 @@ npx prisma migration status --ascii ## Reading the result +### Sample output + +When you do not pass `--db`, the command connects to `db.connection` in `prisma.config.ts`. With one migration applied and one pending, `npx prisma migration status` prints: + +```text +│ migrations: migrations +│ database: postgresql://****@localhost:54329/gaps + +○ a4c3fa7 @contract +│↑ 20260929T1558_add_user_phone 91e7f9f → a4c3fa7 1 ops ⧗ pending +○ 91e7f9f @db (db) +│↑ 20260929T1558_baseline ∅ → 91e7f9f 6 ops ✓ applied +○ ∅ + +⚠ 1 pending — run `prisma db migrate --to a4c3fa7fc3b2` +``` + +Read the drawing from the bottom up, because the earliest state is the bottom row. `∅` is the empty database, before any migration. `@contract` marks the contract in `contract.json`. `@db` marks the contract state that the database's marker records. `(db)` is the `db` [ref](/cli/migration-ref), the file `migrations/app/refs/db.json`, which records the contract state your development database is at. [`db init`](/cli/db-init) writes that file, and so does `db migrate --advance-ref db`. In this output `@db` and `(db)` are on the same row, because the marker and the `db` ref name the same state. [Check before, preview, then apply](/orm/migrations/applying-a-migration#check-before-preview-then-apply) explains each row and each label in more detail. + +The last line suggests the command to run next. It names the pending state by the first 12 characters of its hash, `a4c3fa7fc3b2`, which is the same hash the drawing shortens to 7 characters, `a4c3fa7`. + With `--db`, status reads the marker from the database and compares it with the target. With `--from`, it starts from the state you name instead and needs no database. +### Warnings + +When the command warns with `MIGRATION.MARKER_NOT_IN_HISTORY`, the marker in the database records a contract state that is not in your migration history. This is one kind of drift, and the next `db migrate` on that database fails with `MIGRATION.MARKER_MISMATCH`. To fix it, see [Drift](/orm/migrations/rollbacks-and-recovery#drift-when-the-database-isnt-where-migrations-left-it). + +### JSON output + With `--json`, the command prints one `"kind": "result"` line. Inside its `envelope`: - `result.summary` is the sentence the human output ends with, such as `Up to date` or a count of pending migrations. @@ -50,6 +85,8 @@ With `--json`, the command prints one `"kind": "result"` line. Inside its `envel The exit code is 0 even when `diagnostics` is not empty. A non-zero exit code means the command itself failed, for example with `MIGRATION.REF_NOT_FOUND` when `--to` names a ref that does not exist. +## Related commands + The `migration` group has three more read-only views: `migration graph` draws the chain of migrations, `migration log` lists what has run, and `migration list` lists the migrations on disk. Run each with `--help` for details. Use [`db verify`](/cli/db-verify) after applying migrations to check the final database shape against the emitted contract. diff --git a/apps/docs/content/docs/guides/frameworks/solid-start.mdx b/apps/docs/content/docs/guides/frameworks/solid-start.mdx index d729892fb4..4234a3c642 100644 --- a/apps/docs/content/docs/guides/frameworks/solid-start.mdx +++ b/apps/docs/content/docs/guides/frameworks/solid-start.mdx @@ -398,7 +398,7 @@ check: enabled Skill Package Version Installed into prisma-8 @prisma/orm-postgres 8.0.0-rc.13 .claude/skills, .cursor/skills, .agents/skills, .devin/skills -prisma-composer-core-concepts @prisma/composer 0.23.0 .claude/skills, .cursor/skills, .agents/skills, .devin/skills +prisma-composer-core-concepts @prisma/composer 0.25.0 .claude/skills, .cursor/skills, .agents/skills, .devin/skills prisma-platform-core-concepts prisma 8.0.0-rc.19 .claude/skills, .cursor/skills, .agents/skills, .devin/skills ⚠ [INIT.CONFIG_KEPT] prisma.config.ts already exists, so init left it alone instead of writing the skills section. diff --git a/apps/docs/content/docs/guides/integrations/github-actions.mdx b/apps/docs/content/docs/guides/integrations/github-actions.mdx index 69d009a864..680449a3aa 100644 --- a/apps/docs/content/docs/guides/integrations/github-actions.mdx +++ b/apps/docs/content/docs/guides/integrations/github-actions.mdx @@ -164,7 +164,7 @@ to: 0c3a18eb65d5a5027c444cf0626d843cdb41dfd5fe8e66d6fce8d2eab460c971 app space: migrations/app/20260910T1549_init ``` -`migration plan` is offline. It writes a migration directory under `migrations/app/` and prints a DDL preview; it does not touch the database. Apply it to your development database: +`migration plan` is offline: it writes a migration directory under `migrations/app/` and prints a DDL preview, and it does not touch the database. Apply it to your development database: ```npm npx prisma db migrate @@ -183,11 +183,11 @@ App space └─ marker 0c3a18eb65d5a5027c444cf0626d843cdb41dfd5fe8e66d6fce8d2eab460c971 ``` -Commit the `migrations/` directory. Whenever you change the contract, run `contract emit`, `migration plan --name `, and `db migrate` again; the pull request's database then receives exactly the migrations the pull request adds. See [How migrations work](/orm/migrations/how-migrations-work) for the full loop. +Commit the `migrations/` directory, and whenever you change the contract, run `contract emit`, `migration plan --name `, and `db migrate` again; the pull request's database then receives exactly the migrations the pull request adds. See [How migrations work](/orm/migrations/how-migrations-work) for the full loop. ### 2.5. Seed the database -Create `src/prisma/seed.ts`. Prisma ORM writes take one row at a time and return the inserted row, so create each user, then create its posts with the returned `id`: +Create `src/prisma/seed.ts` with the code below. `User.create()` returns the user it created, and the script uses that user's `id` when it creates the user's posts: ```typescript title="src/prisma/seed.ts" import { db } from "./db.ts"; @@ -292,7 +292,7 @@ await db.close(); ] ``` -The project now works locally. Next, set up the platform side that the workflow will drive. +The project now works locally, so next set up the platform side that the workflow will drive. ## 3. Create a platform project for preview databases @@ -421,7 +421,7 @@ The workflow creates databases in `us-east-1`. Change `PRISMA_POSTGRES_REGION` i ### 4.2. Add the base configuration -Paste the following into `.github/workflows/prisma-postgres-preview.yml`. It sets the triggers, the secrets the CLI reads, and the raw database name: +Paste the following into `.github/workflows/prisma-postgres-preview.yml`, which sets the triggers, the secrets the CLI reads, and the raw database name: ```yaml title=".github/workflows/prisma-postgres-preview.yml" name: Prisma Postgres preview database @@ -741,7 +741,7 @@ Always pass `--project` to the `postgres` commands in CI. From a fresh checkout :::warning -Keep the seed script's `db.close()`. The runtime owns a connection pool that keeps the Node.js process alive, so a script that forgets to close it never exits and the job runs until its timeout. +Keep the `db.close()` at the end of the seed script: without it the connection pool keeps the Node.js process alive after the seed finishes, and the job runs until its timeout. ::: @@ -753,7 +753,7 @@ Use `--json` in every CI step that needs a value back. The `--json` stream ends ## Prompt your coding agent -Run [`npx prisma@latest init`](/cli/init) once to install the [Prisma ORM skills](/ai/tools/skills#available-skills-for-prisma-8) for your coding agent and keep them matching your installed packages. Prompts that map to this guide: +Run [`npx prisma@latest init`](/cli/init) once to install the [Prisma ORM skills](/ai/tools/skills#available-skills-for-prisma-8) for your coding agent and keep them matching your installed packages. `init` and `orm init` are different commands. `orm init` sets up Prisma ORM in a project, and you ran it in [step 2.1](#21-initialize-prisma-orm). `init` installs the agent skills and does not set up Prisma ORM. Prompts that map to this guide: - "Using the prisma-8 skill, add a `Comment` model to the contract, plan a migration for it, and update the seed script." - "Add a test job to the preview workflow that runs `npm test` against the provisioned database after the seed step." diff --git a/apps/docs/content/docs/orm/extensions/using-extensions.mdx b/apps/docs/content/docs/orm/extensions/using-extensions.mdx index c7914e991f..a116ba581b 100644 --- a/apps/docs/content/docs/orm/extensions/using-extensions.mdx +++ b/apps/docs/content/docs/orm/extensions/using-extensions.mdx @@ -206,7 +206,7 @@ export const db = await supabase({ `supabase(...)` takes the same `extensions` array as `postgres(...)`, so pgvector or another extension goes there in the same way. -`await db.asUser(jwt)` takes the user's Supabase JWT and gives you a client that runs as that user. `db.asAnon()` gives you one that runs as the anonymous role, and `db.asServiceRole()` one that bypasses row-level security. `db` itself has no `orm` or `sql`: those live on the three role-bound clients. The [runnable example](https://github.com/prisma/orm/tree/main/examples/supabase) shows the whole setup in one project. +`await db.asUser(jwt)` takes the user's Supabase JWT and gives you a client that runs as that user. `db.asAnon()` gives you one that runs as the anonymous role, and `db.asServiceRole()` one that bypasses row-level security. `db` itself has no `orm` or `sql`: those live on the three role-bound clients. `@prisma/orm-extension-supabase` has a contract of its own, which describes Supabase's `auth` and `storage` tables, check constraints included. Prisma read those tables from one Supabase version, supabase/postgres 17.6.1.106, and a Supabase project on another version can have a different set of check constraints. [`npx prisma db verify`](/cli/db-verify) compares your database with the extension's contract as well as with yours, and when a check constraint the extension describes is missing from your database, `db verify` lists it and fails. You cannot fix that with a migration, because Prisma ORM never changes Supabase's own tables. Instead, [open an issue on prisma/orm](https://github.com/prisma/orm/issues) with the output of `db verify` and your Supabase version, so the extension can be updated to match. @@ -214,8 +214,6 @@ export const db = await supabase({ ::: -If you would rather read a whole working project than a set of snippets, there is a runnable example for each of these extensions: [pgvector](https://github.com/prisma/orm/tree/main/examples/prisma-8-demo), [PostGIS](https://github.com/prisma/orm/tree/main/examples/prisma-8-postgis-demo), [ParadeDB](https://github.com/prisma/orm/tree/main/examples/paradedb-demo), and [Supabase](https://github.com/prisma/orm/tree/main/examples/supabase). - If the extension you need does not exist yet, you can build it. An extension is an npm package with a documented layout, and the [call for extension authors](https://www.prisma.io/blog/prisma-next-call-for-extension-authors) explains how to write and publish one. Once yours is on npm, [submit it to the directory](https://www.prisma.io/extensions/submit), where the form validates your entry and opens the pull request for you. ## See also diff --git a/apps/docs/content/docs/orm/migrations/editing-a-migration.mdx b/apps/docs/content/docs/orm/migrations/editing-a-migration.mdx index 2cf31254b8..b5da3a418e 100644 --- a/apps/docs/content/docs/orm/migrations/editing-a-migration.mdx +++ b/apps/docs/content/docs/orm/migrations/editing-a-migration.mdx @@ -275,7 +275,9 @@ Give each operation a precheck and a postcheck if you can, because they are what ## The same pattern on MongoDB -The same backfill pattern works on MongoDB, with different imports and a differently shaped `check`. Import `dataTransform` from `@prisma/orm-mongo/target/migration`, and write its `check` as an object whose `source` is a callback that returns the query. The example below needs no `db` statements, because it builds its queries directly: `AggregateCommand` for the `check` query and `RawUpdateManyCommand` for the `run` update, both from `@prisma/orm-mongo/query-ast/execution`. A call such as `new RawUpdateManyCommand('products', { status: { $exists: false } }, { $set: { status: 'active' } })` takes the collection name, a filter, and an update. Here those two queries come back from the helpers `existingProductsWithoutStatus` and `backfillRun`, and each of them takes the end contract's `storageHash`, because every MongoDB query records the hash of the contract it was built for. The `setValidation` step is in the listing only because this migration also adds fields to `products`, and the collection's validator has to include them. Both helpers are in the full [retail-store example](https://github.com/prisma/orm/blob/main/examples/retail-store/migrations/app/20260513T0508_backfill_product_status/migration.ts): +The same backfill pattern works on MongoDB, with different imports and a differently shaped `check`. Import `dataTransform` from `@prisma/orm-mongo/target/migration`, and write its `check` as an object whose `source` is a callback that returns the query. The example below needs no `db` statements, because it builds its queries directly: `AggregateCommand` for the `check` query and `RawUpdateManyCommand` for the `run` update, both from `@prisma/orm-mongo/query-ast/execution`. A call such as `new RawUpdateManyCommand('products', { status: { $exists: false } }, { $set: { status: 'active' } })` takes the collection name, a filter, and an update. Here those two queries come back from the helpers `existingProductsWithoutStatus` and `backfillRun`, and each of them takes the end contract's `storageHash`, because every MongoDB query records the hash of the contract it was built for. The `setValidation` step is in the listing only because this migration also adds fields to `products`, and the collection's validator has to include them. + +In this example both helpers are in the same `migration.ts` as the migration. [MongoDB operations](/orm/reference/migration-api#mongodb-operations) in the Migration API reference shows them in full, together with their import. The listing below is the part of the migration that calls them: ```ts title="migration.ts (MongoDB, excerpt)" import { dataTransform, setValidation } from '@prisma/orm-mongo/target/migration'; diff --git a/apps/docs/content/docs/orm/migrations/how-migrations-work.mdx b/apps/docs/content/docs/orm/migrations/how-migrations-work.mdx index 249e53d378..77b316a3d6 100644 --- a/apps/docs/content/docs/orm/migrations/how-migrations-work.mdx +++ b/apps/docs/content/docs/orm/migrations/how-migrations-work.mdx @@ -106,7 +106,7 @@ After `migration plan`, commit the new migration directory, any new directories - the contract hash it starts `from` - the contract hash it ends at, `to` - when it was created -- its own hash, `migrationHash`, which `npx prisma migration check` reads +- its own hash, `migrationHash`, which `npx prisma migration check` uses to find a `migration.json` or `ops.json` that was edited by hand. The hash is computed from the rest of `migration.json` and from `ops.json`, so it changes when either file changes. Do not edit `migration.json` or `ops.json` by hand, because both are written for you from `migration.ts`. Edit `migration.ts` and recompile instead. @@ -122,7 +122,7 @@ Inside `ops.json`, an operation is not only the change itself: it also carries t When `db migrate` reaches an operation, it runs the postcheck first. If the postcheck passes, the change is already in the database, so `db migrate` skips the operation. If it does not pass, `db migrate` runs the precheck, then the statements, then the postcheck again, and it stops the run if either check fails. Once the operations are done, it checks the database against the contract before it updates the marker, which catches a database that satisfied every individual operation but still doesn't match what you declared. -Say `"user"` already has a `phone` column of another type. The postcheck only asks whether a `phone` column exists, so it passes and the operation is skipped. The check against the contract then finds the wrong type, and the run fails with an error whose `code` is `MIGRATION.RUNNER_FAILED` and whose `why:` line reads `The resulting database schema does not satisfy the destination contract.` To see which columns differ, run `npx prisma db verify --schema-only`. Then change the column by hand to the type your contract declares, here `text`, with `ALTER TABLE "public"."user" ALTER COLUMN "phone" TYPE text;`, and run `db migrate` again. [Drift](/orm/migrations/rollbacks-and-recovery#drift-when-the-database-isnt-where-migrations-left-it) covers other changes made outside a migration. +Say `"user"` already has a `phone` column of another type. The postcheck only asks whether a `phone` column exists, so it passes and the operation is skipped. The check against the contract then finds the wrong type, and the run fails with an error whose `code` is `MIGRATION.RUNNER_FAILED` and whose `why:` line reads `The resulting database schema does not satisfy the destination contract.` To see which columns differ, run [`npx prisma db verify --schema-only`](/cli/db-verify), which compares the tables with your contract and skips the marker check. Then change the column by hand to the type your contract declares, here `text`, with `ALTER TABLE "public"."user" ALTER COLUMN "phone" TYPE text;`, and run `db migrate` again. [Drift](/orm/migrations/rollbacks-and-recovery#drift-when-the-database-isnt-where-migrations-left-it) covers other changes made outside a migration. Each operation also has an `operationClass`, which says what kind of change the operation makes to the database and which you choose yourself when you write a raw SQL operation: @@ -148,7 +148,7 @@ The migration commands are part of the [Prisma ORM CLI](/cli) and run as `npx pr | `migration graph` | Draw your [migration history](/orm/migrations/the-migration-graph) as a graph | | `migration check` | Check that each migration's `migrationHash` still matches its files and no files are missing, before you commit a hand edit | -`` is a migration's directory name, its path under `migrations/app/`, or the first 6 or more characters of its `migrationHash`. +`` is a migration's directory name, its path under `migrations/app/`, or the first 6 or more characters of its `migrationHash`. You find a migration's `migrationHash` in its `migration.json`, and `migration show` prints it on the `hash:` line. It is the migration's own hash, not a contract hash, so you cannot pass it to `--from` or `--to`, which take a contract reference, such as a contract hash prefix. [Contract references each command accepts](/orm/migrations/the-migration-graph#contract-reference-forms) lists the forms. The commands in this table connect to a database: @@ -162,7 +162,28 @@ If you used Prisma ORM 7, these commands replace its migrate commands: - `migrate dev` becomes `migration plan`, then `db migrate --advance-ref db`. `migrate dev` also had a second job, making a development database match the contract without writing migration files, and that job is now `db update`, which changes the database directly. [The db ref](/orm/migrations/generating-a-migration#the-db-ref-skipping---from) lists what each of these does to the ref. - `migrate deploy` becomes `db migrate`. -- `migrate reset` has no equivalent. Drop and recreate the database with your own tools, then run `npx prisma db migrate --advance-ref db` to run your migrations again, or `npx prisma db init` to create what your contract declares without running them. +- `migrate reset` has no equivalent. On PostgreSQL, drop the database, create it again, and run your migrations, here for a database named `mydb`: + + ```bash + dropdb --if-exists mydb + createdb mydb + npx prisma db migrate --advance-ref db + ``` + + `dropdb` and `createdb` are PostgreSQL's own command-line tools. They do not read `DATABASE_URL`. They read the server, user, and password from the `PGHOST`, `PGPORT`, `PGUSER`, and `PGPASSWORD` environment variables, which are PostgreSQL's standard ones. `db migrate` does not run a seed script, so run yours afterwards. + + To create the tables your contract declares without running the migrations, replace the last line with [`npx prisma db init`](/cli/db-init). + + If you cannot drop the database, drop both the `public` schema and the `prisma_contract` schema, and then run the same `db migrate` or `db init` command: + + ```sql + DROP SCHEMA public CASCADE; + DROP SCHEMA prisma_contract CASCADE; + ``` + + You do not need to create `public` again, because `db migrate` and `db init` create it. + + Do not drop only `public`, because the marker is in `prisma_contract` and stays in the database. `db migrate` then reports `Already up to date` on a database with no tables, while `db verify` fails. - `migrate diff` becomes `migration show `, which prints one migration, or `db update --dry-run`, which shows the operations that would make a database match the contract. - Baselining, marking an existing database as already migrated, is now [`npx prisma db sign`](/cli/db-sign), which checks that the tables match your contract before it writes the marker. For a database Prisma ORM 7 migrated, follow [Prisma ORM 7 to 8 (PostgreSQL)](/guides/upgrade-prisma-orm/postgresql#4-transfer-migration-ownership). diff --git a/apps/docs/content/docs/orm/migrations/rollbacks-and-recovery.mdx b/apps/docs/content/docs/orm/migrations/rollbacks-and-recovery.mdx index cb52a6937d..eba9a4c1cd 100644 --- a/apps/docs/content/docs/orm/migrations/rollbacks-and-recovery.mdx +++ b/apps/docs/content/docs/orm/migrations/rollbacks-and-recovery.mdx @@ -86,7 +86,9 @@ How much a failed run leaves behind depends on your database, and [when somethin Drift is what you have when your database no longer matches what your migrations say it should. The [marker](/orm/migrations/the-migration-graph#terms-used-on-this-page) is the record in the database of which contract state that database matches, and which kind of drift you have depends on whether the marker is part of the problem. -In the first kind, the marker records a contract state that no migration ends at. You usually get there through [`npx prisma db update`](/cli/db-update), which makes a database match your contract without a migration. The next `db migrate` fails with an error whose `code` is `MIGRATION.MARKER_MISMATCH` before it runs any operation. To fix it, write the migration your history is missing before you change the contract again: run `npx prisma migration plan --from --name `. That migration ends at the state `db update` applied, so the next `db migrate` there has nothing to run. +In the first kind, the marker records a contract state that no migration ends at. You usually get there through [`npx prisma db update`](/cli/db-update), which makes a database match your contract without a migration. The next `db migrate` fails with an error whose `code` is `MIGRATION.MARKER_MISMATCH` before it runs any operation. [`npx prisma migration status`](/cli/migration-status) can warn about the same situation ahead of time, under a different code, `MIGRATION.MARKER_NOT_IN_HISTORY`. The two commands report one problem, so look for `MIGRATION.MARKER_NOT_IN_HISTORY` in `migration status` output and for `MIGRATION.MARKER_MISMATCH` in `db migrate` output. + +To fix it, write the migration your history is missing before you change the contract again: run `npx prisma migration plan --from --name `. That migration ends at the state `db update` applied, so the next `db migrate` there has nothing to run. In the second kind, only tables or columns changed, for example with a hand-run `ALTER`. The marker still records the last contract state applied, so `db migrate` still runs. It skips an operation whose change is already in the database, and it fails if an operation's check fails, or if your contract describes something missing or different once the operations have run. diff --git a/apps/docs/content/docs/orm/migrations/the-migration-graph.mdx b/apps/docs/content/docs/orm/migrations/the-migration-graph.mdx index 22dbaf065c..ba21e80df5 100644 --- a/apps/docs/content/docs/orm/migrations/the-migration-graph.mdx +++ b/apps/docs/content/docs/orm/migrations/the-migration-graph.mdx @@ -42,6 +42,8 @@ Keep `--advance-ref db` on that command in development, so that your next `migra | **Marker** | The record in the database of which contract state it matches. Reading it does not check the tables. | | **Ledger** | The database's own list of every migration applied to it, and when each ran. | | **Ref** | A name for a contract state, like `prod`, stored as a file in `migrations/app/refs/`. | +| **Contract reference** | The text a command accepts to name a contract state, such as a hash prefix or a ref name. [Contract references each command accepts](#contract-reference-forms) lists the forms. | +| **`^`** | A migration directory name followed by `^`. It names the contract state before that migration, while the directory name alone names the state after it. | | **Contract space** | A separate migration history with its own directory in `migrations/`. Your app's is `migrations/app/`. Each [Prisma ORM extension package](/orm/extensions/using-extensions) that ships migrations, such as pgvector support, has its own, and one `db migrate` run applies all of them, as [Extension spaces](/orm/migrations/applying-a-migration#extension-spaces) shows. | ## How it works @@ -77,7 +79,9 @@ npx prisma migration graph 1 space(s), 5 contract(s), 4 migration(s) ``` -Read it from the bottom up, because the earliest state is the bottom row and every row above it is a later one. Each `↑` row shows a migration's directory name, its start and end hashes, and its operation count, and `--legend` prints a key to the other symbols. +Read it from the bottom up, because the earliest state is the bottom row and every row above it is a later one. Each `↑` row shows a migration's directory name, its start and end hashes, and its operation count. The lines on the left are drawn in columns, one column for each branch of the history. Where a row belongs to one branch, the other branch's column shows a `│`, so you can follow that column up the page. The `│─╯` row shows where the two columns split: Bob's migration, in the right-hand column, and Alice's, in the left-hand column, both start from `4437973`. + +To print a key to the symbols in the rows, run `npx prisma migration graph --legend`. The key explains `○`, the arrows, `∅`, the `@contract` and `@db` labels, and ref labels such as `(prod)`. It also explains `✓`, which means applied, and `⧗`, which means pending, and you see those two in `migration status` output. From an empty database (`∅`), `init` produces contract state `4437973`. Alice's migration starts there and produces `5e1f082`, and Bob's starts from the same state and produces `1a76a3c`, which is why the drawing splits in two. Bob merged first, so `main` now points the `prod` ref at `1a76a3c`, and production will be migrated there. Alice's branch still holds a migration that starts from `4437973`, which is no longer the head. @@ -111,10 +115,6 @@ When no chain of migrations leads from the marker to the target, the run fails w `migration log` reads the **ledger**, so it tells you what actually ran rather than what should have run, and a rollback appears there as one more applied migration instead of erasing anything. Run `migration check` before you commit a migration you edited, and after you move a ref. It catches an `ops.json` or `migration.json` that was changed by hand, and a ref naming a state that does not exist, and it needs no database connection. A deploy pipeline does not need it: `db migrate --to ` refuses a hand-edited migration file on its own. See [Reviewing what you planned](/orm/migrations/generating-a-migration#reviewing-what-you-planned) for its exit codes. -### Try it on real fixtures - -The [Prisma ORM repository](https://github.com/prisma/orm) has branched histories, including a `diamond` fixture with the same `init`, `alice_add_phone`, and `bob_add_avatar` migrations, in `examples/prisma-8-demo/fixtures/`. To draw one, build the repository and pass the example's `prisma.config.ts` to `migration graph` with `--config`. - ## Name important states with refs Hashes are hard to remember and hard to talk about, so Prisma ORM lets you give the states that matter a name of your own. A **ref** is that name: you create one and point it at a state with `npx prisma migration ref set`, and then you pass the name instead of a hash, for example to `db migrate --to`. The name `prod` below is only an example: @@ -127,7 +127,7 @@ npx prisma db migrate --to prod A ref named for an environment, such as `prod` or `staging`, names the contract state your deploy pipeline will migrate that environment to. It is a promise the repository makes, not a record of what is deployed; the marker in the database records that. Point it at the new state when a change merges to `main`, and have the pipeline run `db migrate --to prod` so it never applies more than the repository has promised. -To say which state a ref should point at, `ref set` takes a hash or a prefix of one, a ref name, a migration directory name, or `^`, but none of the `@` tokens below. Once the ref exists, `db migrate --to prod` applies migrations until the database matches the state `prod` names, and the database it changes is the one `prisma.config.ts` connects to, unless you pass a connection string with `--db`. +`ref set` points a ref at a contract state, and [the table below](#contract-reference-forms) lists the forms it accepts. One of them is `^`, a migration directory name followed by `^`. It names the contract state before that migration, while the directory name alone names the state after it. Once the ref exists, `db migrate --to prod` applies migrations until the database matches the state `prod` names, and the database it changes is the one `prisma.config.ts` connects to, unless you pass a connection string with `--db`. Some states you only need to refer to once, so Prisma ORM reserves a few tokens that start with `@`. Each names a contract state without creating a ref: @@ -135,7 +135,28 @@ Some states you only need to refer to once, so Prisma ORM reserves a few tokens - `@db`: the contract state in the marker of the database you are connected to. The `db` ref is a file, so it can name a different state. - `@empty`: the empty database, before any migration. -Not every command takes every token. `migration plan` is offline and cannot read a database, so of the three its `--from` takes only `@empty`; each command's reference lists what it accepts, such as [`db migrate --show`](/cli/db-migrate#options). So if you want to see the path from the contract you have now to the state `prod` names, without changing anything, run `npx prisma db migrate --show --from @contract --to prod`. +### Contract references each command accepts [#contract-reference-forms] + +Not every command accepts every form. This table lists what each one accepts: + +| Command and option | Accepts | +| --- | --- | +| `migration plan --from` | a hash, a hash prefix, a ref name, a migration directory name, `^`, or `@empty` | +| `migration plan --to` | a hash, a hash prefix, a ref name, a migration directory name, or `^` | +| `migration new --from` | a hash, or a prefix of one, that an existing migration ends at | +| `migration ref set ` | a hash, a hash prefix, a ref name, a migration directory name, or `^` | +| `migration status --from`, `--to` | a hash, a hash prefix, a ref name, a migration directory name, `^`, or `@empty` | +| `db migrate --to` | a hash, a hash prefix, a ref name, a migration directory name, or `^` | +| `db migrate --show --to` | a hash, a hash prefix, a ref name, a migration directory name, `^`, `@contract`, or `@empty` | +| `db migrate --show --from` | a hash, a hash prefix, a ref name, a migration directory name, `^`, `@contract`, `@db`, or `@empty` | +| `db update --to` | a hash, a hash prefix, a ref name, a migration directory name, or `^` | +| `db sign [contract]`, `--contract` | a hash, a hash prefix, a ref name, a migration directory name, or `^` | + +A hash prefix is the first 6 or more characters of a hash, and it must match exactly one contract state. None of these options accepts a file path. + +The table lists only what you can pass. To read what an option does, open the command's page in the [CLI reference](/cli), such as [`migration status`](/cli/migration-status). + +For example, to see the path from the contract you have now to the state `prod` names, without changing anything, run `npx prisma db migrate --show --from @contract --to prod`. ## What the graph gives you @@ -145,7 +166,7 @@ Two branches can plan migrations at the same time without either one knowing abo ### History you can trust -A migration only ever runs against a database that matches the state it starts `from`. Before any operation runs, `db migrate` checks that the marker is a state in your migration history and stops if it is not. That check reads only the marker, not the tables. `db migrate` checks the tables only after it has run operations, and never when it has nothing to run, so to compare the tables against your contract directly, run `npx prisma db verify --schema-only`. +A migration only ever runs against a database that matches the state it starts `from`. Before any operation runs, `db migrate` checks that the marker is a state in your migration history and stops if it is not. That check reads only the marker, not the tables. `db migrate` checks the tables only after it has run operations, and never when it has nothing to run. To check the tables yourself, run [`npx prisma db verify --schema-only`](/cli/db-verify), which compares the tables with your contract and skips the marker check. That marker check is also what you run into after using `npx prisma db update`, which, like Prisma ORM 7's `db push`, changes a database to match the contract without writing a migration. Because the contract it applied is one that no migration ends at, your next `db migrate` run stops at the check. [Drift](/orm/migrations/rollbacks-and-recovery#drift-when-the-database-isnt-where-migrations-left-it) explains what to do next. @@ -178,7 +199,7 @@ Nothing above changes with your database, because the graph and the commands are `npx prisma migration new` writes an empty migration for a change you write yourself, such as a data update. The migration always ends at the contract state in your current `contract.json`. Without `--from`, it starts where `migration plan` would: at the `db` ref, or at an empty database when there are no migrations and no `db` ref yet. When there are migrations but no `db` ref, it stops and asks for `--from`. [`migration new`](/cli/migration-new) lists every case. -Unlike the `--from` of `migration plan`, the `--from` of `migration new` takes only a contract hash that an existing migration ends at, which is the `to` hash in that migration's `migration.json`. You can shorten the hash to its first characters, such as the 7 that `migration graph` shows, as long as they match only one migration's `to` hash. It does not take a ref name, a migration directory name, or an `@` name such as `@db`. So to start from `e377d00` in the drawing above, run `npx prisma migration new --name backfill --from e377d00`. Because `e377d00` is also the `@contract` state, that migration starts and ends at the same state, which is what a data-only migration does. +Unlike the `--from` of `migration plan`, the `--from` of `migration new` takes only a contract hash that an existing migration ends at, which is the `to` hash in that migration's `migration.json`. You can shorten the hash to its first characters, such as the 7 that `migration graph` shows, as long as they match only one migration's `to` hash. It does not take a ref name, a migration directory name, or an `@` name such as `@db`. [Contract references each command accepts](#contract-reference-forms) compares it with the other commands. So to start from `e377d00` in the drawing above, run `npx prisma migration new --name backfill --from e377d00`. Because `e377d00` is also the `@contract` state, that migration starts and ends at the same state, which is what a data-only migration does. ## Release-candidate limitations diff --git a/apps/docs/content/docs/orm/reference/error-reference.mdx b/apps/docs/content/docs/orm/reference/error-reference.mdx index 4b93312eb4..bc2b5d7080 100644 --- a/apps/docs/content/docs/orm/reference/error-reference.mdx +++ b/apps/docs/content/docs/orm/reference/error-reference.mdx @@ -7,10 +7,10 @@ metaDescription: Every structured error code Prisma ORM can emit, by namespace, --- {/* Generated by scripts/generate-error-reference.mjs from - https://github.com/prisma/prisma/blob/main/docs/reference/error-reference.md + https://github.com/prisma/orm/blob/main/docs/reference/error-reference.md Do not edit by hand — changes are overwritten by the sync workflow. */} -Every user-facing Prisma ORM error is a structured envelope identified by a dotted `NAMESPACE.SUBCODE` code (see [ADR 239](https://github.com/prisma/prisma/blob/main/docs/architecture%20docs/adrs/ADR%20239%20-%20Errors%20are%20structural%20envelopes%20with%20dotted%20namespace%20codes.md) and [Error Handling](https://github.com/prisma/prisma/blob/main/docs/Error%20Handling.md)). This page lists every published code. Each code anchors as `#` — the exact fragment every emitted error carries in its `docsUrl`. This page is generated from the canonical reference in the `prisma/prisma` repository, whose CI requires every code in production source to be documented before it ships. +Every user-facing Prisma ORM error is a structured envelope identified by a dotted `NAMESPACE.SUBCODE` code (see [ADR 239](https://github.com/prisma/orm/blob/main/docs/architecture%20docs/adrs/ADR%20239%20-%20Errors%20are%20structural%20envelopes%20with%20dotted%20namespace%20codes.md) and [Error Handling](https://github.com/prisma/orm/blob/main/docs/Error%20Handling.md)). This page lists every published code. Each code anchors as `#` — the exact fragment every emitted error carries in its `docsUrl`. This page is generated from the canonical reference in the `prisma/orm` repository, whose CI requires every code in production source to be documented before it ships. Recognize an error programmatically with `isStructuredError` from your facade package's `utils/structured-error` subpath (for example `@prisma/orm-postgres/utils/structured-error`) and match on `error.code`, never `instanceof`. Envelopes carry `message`, and optionally `why`, `fix`, `where`, `cause`, `docsUrl`, and the structured context each entry below lists as its **Payload**. The payload arrives on `error.meta` when the envelope was built by `structuredError` and on `error.details` when it was built by `runtimeError`; a few codes are raised both ways, so read whichever property the envelope carries. @@ -20,7 +20,7 @@ Some codes are not failures to run at all. `db verify`, `db sign` and `migration A command may also **complete with findings**: it ran to its end and has a result to report, and the problems it found ride that result as diagnostics carrying the codes on this page. Those runs exit with a documented per-command code in the `4`–`99` band rather than `2`, and the entry below says so. `prisma orm init` is the case today: its scaffold is on disk whatever happens next, so a failed dependency install or contract emit is a finding on a completed run at exit `4` or `5`. -Codes that predate the dotted scheme were renamed at 0.16; the full old→new crosswalk (`PN-DOMAIN-NNNN` → `NAMESPACE.SUBCODE`) is in [ADR 239](https://github.com/prisma/prisma/blob/main/docs/architecture%20docs/adrs/ADR%20239%20-%20Errors%20are%20structural%20envelopes%20with%20dotted%20namespace%20codes.md). +Codes that predate the dotted scheme were renamed at 0.16; the full old→new crosswalk (`PN-DOMAIN-NNNN` → `NAMESPACE.SUBCODE`) is in [ADR 239](https://github.com/prisma/orm/blob/main/docs/architecture%20docs/adrs/ADR%20239%20-%20Errors%20are%20structural%20envelopes%20with%20dotted%20namespace%20codes.md). Namespaces: @@ -231,7 +231,7 @@ A `package.json` found while resolving the project import root exists but could ### CLI.PROMPT_REQUIRED [#CLI.PROMPT_REQUIRED] -Raised by `@prisma/cli-engine`, not by this repository: a command asked a question that has no default, and the session could not show it: stdin is not a terminal, `--no-interactive` was passed, or `--yes` was asked to answer a prompt that declares no default. The `CLI` namespace is shared with the engine (see [ADR 239](https://github.com/prisma/prisma/blob/main/docs/architecture%20docs/adrs/ADR%20239%20-%20Errors%20are%20structural%20envelopes%20with%20dotted%20namespace%20codes.md)); it is listed here because it settles runs of the ORM's commands. `prisma orm init` translates it for the two prompts that stand in for a required flag, so a missing `--target` or `--authoring` still reports `CLI.INIT_MISSING_FLAGS` with the full missing list. Payload: none. +Raised by `@prisma/cli-engine`, not by this repository: a command asked a question that has no default, and the session could not show it: stdin is not a terminal, `--no-interactive` was passed, or `--yes` was asked to answer a prompt that declares no default. The `CLI` namespace is shared with the engine (see [ADR 239](https://github.com/prisma/orm/blob/main/docs/architecture%20docs/adrs/ADR%20239%20-%20Errors%20are%20structural%20envelopes%20with%20dotted%20namespace%20codes.md)); it is listed here because it settles runs of the ORM's commands. `prisma orm init` translates it for the two prompts that stand in for a required flag, so a missing `--target` or `--authoring` still reports `CLI.INIT_MISSING_FLAGS` with the full missing list. Payload: none. ### CLI.UNEXPECTED [#CLI.UNEXPECTED] @@ -805,11 +805,11 @@ A written `@default` value has a data type the column's type neither is nor cast The same code reports a written form this target has no data type for at all: `Field "."[ at element ]: this target has no data type for a value` — `true` on SQLite, for instance, which registers no boolean entry. -Reported at the `@default` attribute. See [ADR 254](https://github.com/prisma/prisma/blob/main/docs/architecture%20docs/adrs/ADR%20254%20-%20Data%20types%20and%20casts.md). +Reported at the `@default` attribute. See [ADR 254](https://github.com/prisma/orm/blob/main/docs/architecture%20docs/adrs/ADR%20254%20-%20Data%20types%20and%20casts.md). ### PSL_INVALID_DEFAULT_LITERAL [#PSL_INVALID_DEFAULT_LITERAL] -A written `@default` value that whatever read it refused: the authoring entry's parse, a cast, or the column's codec. A `pgvector.Vector(3)` column given two elements, a magnitude no double holds written on a `Float` column, a body a tag's parse cannot read, or a number no data type of the target holds — `no data type of this target holds the number `, which is how SQLite refuses a whole number past 64 bits. The message is `Field ".": `, with ` at element ` after the field path when it is one element of a written list. Reported at the `@default` attribute. See [ADR 254](https://github.com/prisma/prisma/blob/main/docs/architecture%20docs/adrs/ADR%20254%20-%20Data%20types%20and%20casts.md). +A written `@default` value that whatever read it refused: the authoring entry's parse, a cast, or the column's codec. A `pgvector.Vector(3)` column given two elements, a magnitude no double holds written on a `Float` column, a body a tag's parse cannot read, or a number no data type of the target holds — `no data type of this target holds the number `, which is how SQLite refuses a whole number past 64 bits. The message is `Field ".": `, with ` at element ` after the field path when it is one element of a written list. Reported at the `@default` attribute. See [ADR 254](https://github.com/prisma/orm/blob/main/docs/architecture%20docs/adrs/ADR%20254%20-%20Data%20types%20and%20casts.md). ### PSL_INVALID_JSON_LITERAL [#PSL_INVALID_JSON_LITERAL] @@ -1155,7 +1155,7 @@ Executing a prepared statement without supplying a value for one of its declared ### RUNTIME.RAW_ROW_COLUMN_MISSING [#RUNTIME.RAW_ROW_COLUMN_MISSING] -A whole-query raw statement returned a result that omits a column its row spec declares. The runtime never parses the SQL, so the spec is its only description of the result: a column the spec names and the statement does not return is a mismatch the caller has to resolve, by correcting the spec or the statement. Distinct from `RUNTIME.DECODE_FAILED`, which means a codec rejected a value the runtime did expect. Surplus result columns the spec does not declare are dropped silently and never raise this. See [ADR 247](https://github.com/prisma/prisma/blob/main/docs/architecture%20docs/adrs/ADR%20247%20-%20Whole-query%20raw%20SQL%20is%20the%20fragment%20mechanism%20at%20statement%20position.md). Payload: `column`, `declaredColumns`, `resultColumns`. +A whole-query raw statement returned a result that omits a column its row spec declares. The runtime never parses the SQL, so the spec is its only description of the result: a column the spec names and the statement does not return is a mismatch the caller has to resolve, by correcting the spec or the statement. Distinct from `RUNTIME.DECODE_FAILED`, which means a codec rejected a value the runtime did expect. Surplus result columns the spec does not declare are dropped silently and never raise this. See [ADR 247](https://github.com/prisma/orm/blob/main/docs/architecture%20docs/adrs/ADR%20247%20-%20Whole-query%20raw%20SQL%20is%20the%20fragment%20mechanism%20at%20statement%20position.md). Payload: `column`, `declaredColumns`, `resultColumns`. ### RUNTIME.RAW_SQL_UNSUPPORTED_INTERPOLATION [#RUNTIME.RAW_SQL_UNSUPPORTED_INTERPOLATION] diff --git a/apps/docs/content/docs/orm/reference/migration-api.mdx b/apps/docs/content/docs/orm/reference/migration-api.mdx index d96d9dbd60..d3f1db392e 100644 --- a/apps/docs/content/docs/orm/reference/migration-api.mdx +++ b/apps/docs/content/docs/orm/reference/migration-api.mdx @@ -456,7 +456,7 @@ CREATE TABLE "public"."post" ( ) ``` -## MongoDB operations +## MongoDB operations [#mongodb-operations] A MongoDB `migration.ts` has the same shape, and everything comes from one module: @@ -466,7 +466,7 @@ import { Migration, MigrationCLI, placeholder, createCollection, dropCollection, The operations are plain functions rather than methods, so `operations` returns calls such as `createCollection('products')`, not `this.createCollection(...)`. `this.endContract.collection.products` is the `products` collection in the end contract, with its `validator`. -A data transform's `run` callback returns a query object with three fields: the `collection`, a `command` such as `RawUpdateManyCommand`, and `meta`, which carries `storageHash`, the hash of the end contract. The check's `source` returns the same kind of object with an `AggregateCommand`. These two helpers are from the [retail-store example](https://github.com/prisma/orm/blob/main/examples/retail-store/migrations/app/20260513T0508_backfill_product_status/migration.ts); the first finds documents with no `status` and limits to one, and the second sets it, where `RawUpdateManyCommand` takes the collection name, a filter, and an update: +A data transform's `run` callback returns a query object with three fields: the `collection`, a `command` such as `RawUpdateManyCommand`, and `meta`, which carries `storageHash`, the hash of the end contract. The check's `source` returns the same kind of object with an `AggregateCommand`. In this example both helpers are in the same `migration.ts` as the migration. The first helper is the query for the check, and it finds one document that has no `status`. The second helper sets `status` to `'active'` on every document that has none. `RawUpdateManyCommand` takes the collection name, a filter, and an update: ```ts import { diff --git a/apps/docs/cspell.json b/apps/docs/cspell.json index 3b72dc1516..4fd725f1d7 100644 --- a/apps/docs/cspell.json +++ b/apps/docs/cspell.json @@ -266,9 +266,13 @@ "pgcat", "pgcrypto", "pgfence", + "pghost", "pgloader", + "pgpassword", + "pgport", "pgrowlocks", "pgstattuple", + "pguser", "pgvector", "phraseto", "PKCE", diff --git a/apps/docs/scripts/generate-error-reference.mjs b/apps/docs/scripts/generate-error-reference.mjs index ab35da4161..67f86c1b6b 100644 --- a/apps/docs/scripts/generate-error-reference.mjs +++ b/apps/docs/scripts/generate-error-reference.mjs @@ -5,7 +5,7 @@ // node scripts/generate-error-reference.mjs [--target orm|cli] [--source ] // // Targets: -// orm (default) prisma/prisma -> content/docs/orm/reference/error-reference.mdx +// orm (default) prisma/orm -> content/docs/orm/reference/error-reference.mdx // cli prisma/prisma-cli -> content/docs/cli/error-reference.mdx // // Without --source, the file is fetched from raw.githubusercontent.com. @@ -91,12 +91,12 @@ function applyCliNamingStandard(body) { export const TARGETS = { orm: { - sourceRepo: "prisma/prisma", + sourceRepo: "prisma/orm", output: join(HERE, "../content/docs/orm/reference/error-reference.mdx"), applyNamingStandard: applyOrmNamingStandard, hostedIntro: "Each code anchors as `#` — the exact fragment every emitted error carries in its " + - "`docsUrl`. This page is generated from the canonical reference in the `prisma/prisma` " + + "`docsUrl`. This page is generated from the canonical reference in the `prisma/orm` " + "repository, whose CI requires every code in production source to be documented before it ships.", frontmatter: `--- title: Error reference