diff --git a/apps/docs/content/docs/(index)/full-stack-tutorial.mdx b/apps/docs/content/docs/(index)/full-stack-tutorial.mdx index 17fb5f869e..832f72cf32 100644 --- a/apps/docs/content/docs/(index)/full-stack-tutorial.mdx +++ b/apps/docs/content/docs/(index)/full-stack-tutorial.mdx @@ -219,7 +219,7 @@ npx prisma migration plan --name add-user-role --from _init The plan is your change and nothing else. Review it like any other diff, with [`migration show`](/cli/migration-show) or by reading the generated package: ```text no-copy -ALTER TABLE "public"."user" ADD COLUMN "role" text DEFAULT 'member' NOT NULL +ALTER TABLE "public"."User" ADD COLUMN "role" text DEFAULT 'member' NOT NULL ``` Emitting also updated the query types, so surface the new field in the route's typed select in `src/prisma/users.ts`, adding `"role"` to the `.select(...)` list and `role: user.role` to the returned object: diff --git a/apps/docs/content/docs/(index)/prisma-orm/add-to-existing-project/postgresql.mdx b/apps/docs/content/docs/(index)/prisma-orm/add-to-existing-project/postgresql.mdx index 0296fe3c78..7c609dd69f 100644 --- a/apps/docs/content/docs/(index)/prisma-orm/add-to-existing-project/postgresql.mdx +++ b/apps/docs/content/docs/(index)/prisma-orm/add-to-existing-project/postgresql.mdx @@ -84,7 +84,7 @@ npx prisma contract infer --output ./src/prisma/contract.prisma The command writes a first draft of `src/prisma/contract.prisma`. -Open that file and review it before you go on. This is the moment to clean up model names, keep only the tables you want Prisma ORM to know about first, and make the file easier to read. +Open that file and review it before you go on. This is the moment to clean up model names, keep only the tables you want Prisma ORM to know about first, and make the file easier to read. A model's table is the model name exactly as written, so a table such as `User` gets a model with no `@@map`, and a table such as `user` or `user_profile` gets `@@map` with its name. Keep those `@@map` lines when you rename a model, so the table stays the same. :::note[Temporal types on inferred date and time columns] 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 e64a297b7a..9eaa2c097f 100644 --- a/apps/docs/content/docs/(index)/prisma-orm/from-scratch.mdx +++ b/apps/docs/content/docs/(index)/prisma-orm/from-scratch.mdx @@ -122,13 +122,13 @@ npx prisma db init │ database: postgres://****:****@db.prisma.io:5432/postgres?sslmode=require ✔ Applied 2 operation(s) across 1 contract space App space -├─ Create table "user" -├─ Add unique constraint on "user" (email) +├─ Create table "User" +├─ Add unique constraint on "User" (email) └─ marker f4e1954fd8bed87828d13c3f1a02164dc9796ef1af76ed6f98184c01263169c5 ✔ Advanced ref "db" → f4e1954fd8bed87828d13c3f1a02164dc9796ef1af76ed6f98184c01263169c5 ``` -It also writes `migrations/app/refs/db.json` and a snapshot of the contract under `migrations/snapshots/`; commit both. 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. +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 @@ -215,13 +215,13 @@ npx prisma migration plan --name add_user_phone ```text ✔ Planned baseline + 1 operation(s) migrations/app/20260917T1457_add_user_phone -└─ Add column "phone" to "user" +└─ Add column "phone" to "User" from: f4e1954fd8bed87828d13c3f1a02164dc9796ef1af76ed6f98184c01263169c5 to: a8a6806fd2d219065fd4449b295c80626e9123c18bd40847ec3588aa9d565bc9 baseline: migrations/app/20260917T1456_baseline app space: migrations/app/20260917T1457_add_user_phone ℹ DDL preview -ALTER TABLE "public"."user" ADD COLUMN "phone" text; +ALTER TABLE "public"."User" ADD COLUMN "phone" text; ``` Two directories appear under `migrations/app/`: a baseline that records the table `db init` created, and your change. The baseline is never applied to this database, because the database is already signed at that state. Each migration directory holds a `migration.ts` you can read and edit; [Generating a migration](/orm/migrations/generating-a-migration) explains the files. @@ -235,7 +235,7 @@ npx prisma db migrate --advance-ref db ```text ✔ Applied 1 migration(s) (1 operation(s)) across 1 contract space(s) App space -├─ Add column "phone" to "user" +├─ Add column "phone" to "User" └─ marker a8a6806fd2d219065fd4449b295c80626e9123c18bd40847ec3588aa9d565bc9 ✔ Advanced ref "db" → a8a6806fd2d219065fd4449b295c80626e9123c18bd40847ec3588aa9d565bc9 ``` diff --git a/apps/docs/content/docs/cli/configuration.mdx b/apps/docs/content/docs/cli/configuration.mdx index 6ed4f5a3f6..eb366b6f70 100644 --- a/apps/docs/content/docs/cli/configuration.mdx +++ b/apps/docs/content/docs/cli/configuration.mdx @@ -6,7 +6,7 @@ metaTitle: Prisma ORM CLI configuration metaDescription: 'Learn how Prisma ORM CLI commands find config, read database URLs, and format output.' --- -Prisma ORM CLI commands read `prisma.config.ts` in your project root. The file has one section per part of the CLI. The Prisma ORM data commands read the `orm` section; the [agent skills commands](/cli/skills) read the `skills` section. +Prisma ORM CLI commands read `prisma.config.ts`, starting in the directory you run them from. The file has one section per part of the CLI. The `contract`, `db`, and `migration` commands read the `orm` section, and the [agent skills commands](/cli/skills) read the `skills` section. ## Config file @@ -27,14 +27,104 @@ export default definePrismaConfig({ }); ``` -For MongoDB projects, import the section helper from `@prisma/orm-mongo/config` instead. `defineConfig` from `@prisma/cli-engine` is the former name of `definePrismaConfig` and still works, so configs scaffolded by earlier release candidates keep evaluating. +For MongoDB projects, import the section helper from `@prisma/orm-mongo/config` instead. Both packages export this helper as `defineConfig`, and the examples on this page rename it to `ormConfig` when they import it. -[`orm init`](/cli/orm-init) writes this file for you. Pass `--config` when your config file is not at `./prisma.config.ts`: +If you set up Prisma ORM 8 with a release candidate before `8.0.0-rc.12`, your config may import `defineConfig` from `@prisma/cli-engine`, the package the `prisma` CLI is built on. `8.0.0-rc.12` requires `@prisma/cli-engine` 0.6.1, which removed that export, so the config fails to load. Rename that import and its call to `definePrismaConfig`, which is the same function under its new name. You can import it from `prisma/config` or from `@prisma/cli-engine`, because `prisma/config` re-exports it. Leave the `defineConfig` import from `@prisma/orm-postgres/config` or `@prisma/orm-mongo/config` as it is: that is the helper for the `orm` section, and its name has not changed. + +[`orm init`](/cli/orm-init) writes this file for you. Without `--config`, the CLI looks for `prisma.config.ts` in the directory you run the command from and in the directories above it, as [How the CLI finds the config](#how-the-cli-finds-the-config) explains. Pass `--config` to use a config file in another place, such as a subdirectory: ```npm npx prisma contract emit --config ./config/prisma.config.ts ``` +## How the CLI finds the config + +The CLI looks for `prisma.config.ts` in the current directory, or starts from the file you pass to `--config`. It then looks in each parent directory, up to the root of the repository, which is the first directory that has a `.git` entry. If neither the starting directory nor any directory above it has a `.git` entry, the CLI reads only the first file. + +The CLI combines the files it finds one section at a time. Inside a section such as `orm`, each top-level key, such as `contract`, `db`, or `migrations`, comes whole from the nearest file that sets it, and the keys nested inside it are not combined. So if a config higher up sets `db.connection` and your project's config sets only `contract`, the CLI uses your `contract` and the other file's `db`. Extensions are the exception: a project config that calls `ormConfig` does not inherit them from a config higher up, even when it leaves `extensions` out. List the extensions your contract uses in each project's own config. + +A project inside a larger repository therefore inherits any setting its own config leaves out from a `prisma.config.ts` higher up. + +:::warning[More than one project in a repository] + +If a `prisma.config.ts` higher up sets `db` or `migrations`, a project config that leaves them out uses that file's database and migrations folder. `db update`, `db migrate` and `db verify` then connect to the other project's database, and `migration plan` writes into the other project's migrations folder, without a warning. Set `db` and `migrations` in every project's own config, or add `parent: false` to it. + +::: + +To stop a project's config from inheriting anything, add `parent: false` to it. The search then ends at that file: + +```typescript title="prisma.config.ts" +import { definePrismaConfig } from "prisma/config"; +import { defineConfig as ormConfig } from "@prisma/orm-postgres/config"; + +export default definePrismaConfig({ + parent: false, + orm: ormConfig({ + contract: "./prisma/contract.prisma", + }), +}); +``` + +`parent` can also be a path to another config file, which the CLI reads next in place of the one in the parent directory. The path is relative to the directory of the config file that sets it, and it may point outside the repository. After reading that file, the CLI goes on to search the directories above it in the usual way, unless that file sets `parent` too: + +```typescript title="prisma.config.ts" +import { definePrismaConfig } from "prisma/config"; +import { defineConfig as ormConfig } from "@prisma/orm-postgres/config"; + +export default definePrismaConfig({ + parent: "../shared/prisma.config.ts", + orm: ormConfig({ + contract: "./prisma/contract.prisma", + }), +}); +``` + +A relative path in a config file, such as `contract`, `output`, or `migrations.dir`, resolves from the directory of the config file that sets it, not from the directory you run the command in. So `--config ./config/prisma.config.ts` with `contract: "./prisma/contract.prisma"` reads `./config/prisma/contract.prisma`. + +## Split the schema across several files + +`contract` accepts a glob, a path pattern where `*` matches any file name and `**` matches any number of folders, so one schema can span several `.prisma` files: + +```typescript title="prisma.config.ts" +import { definePrismaConfig } from "prisma/config"; +import { defineConfig as ormConfig } from "@prisma/orm-postgres/config"; + +export default definePrismaConfig({ + orm: ormConfig({ + contract: "./prisma/**/*.prisma", + }), +}); +``` + +`contract emit` builds one contract from every matched file whose first line is `// use prisma-8`. It skips a matched file without that line and does not warn, so the line is what makes a file part of the schema. The Prisma editor extension uses the same rule, so the editor and `contract emit` agree on which files make up the schema. If the glob matches files but none of them starts with the line, `contract emit` fails with `CONTRACT.SOURCE_LOAD_FAILED`, and the error's finding is `PSL_NO_OPTED_IN_SCHEMA_FILES`. If the glob matches no file at all, for example because of a typo in the pattern, the finding is `PSL_NO_SCHEMA_FILES_MATCHED` instead. + +A new file joins the schema the next time you run `contract emit`, with no change to the config. The emitted files go in the folder before the first wildcard, here `./prisma/contract.json` and `./prisma/contract.d.ts`. + +## Use a Prisma ORM 7 schema + +On PostgreSQL, Prisma ORM 8 can read a Prisma ORM 7 `schema.prisma` directly as its contract source, so the two versions can run side by side on the database that Prisma ORM 7 migrates. Wrap the path in `prisma7Schema`: + +```typescript title="prisma.config.ts" +import "dotenv/config"; +import { definePrismaConfig } from "prisma/config"; +import { defineConfig as ormConfig, prisma7Schema } from "@prisma/orm-postgres/config"; + +export default definePrismaConfig({ + orm: ormConfig({ + contract: prisma7Schema("prisma/schema.prisma"), + db: { + connection: process.env["DATABASE_URL"]!, + }, + }), +}); +``` + +`prisma7Schema` takes one schema file, or a directory of `.prisma` files as Prisma ORM 7 reads it. It reads every `.prisma` file it is given, so these files do not need the `// use prisma-8` first line. `contract emit` writes `contract.json` and `contract.d.ts` into the directory that holds the schema, here `prisma/`, unless you set `output`. Prisma ORM 7 keeps owning the database and its migrations, and you run its commands as `prisma7`, the Prisma ORM 7 CLI that [`orm init --from-prisma7-schema`](/cli/orm-init#on-a-prisma-orm-7-project) installs next to Prisma ORM 8. + +Once the config is in place, run `npx prisma contract emit` and then [`npx prisma db sign`](/cli/db-sign). `db sign` checks that the database matches the contract and then records that in the database, without changing your tables. Run both commands again after each Prisma ORM 7 migration, whether you ran `npx prisma7 migrate dev` or `npx prisma7 migrate deploy`, so that the record names the new contract. + +`contract emit` fails on any part of the schema that Prisma ORM 8 cannot represent exactly, such as a `view` block, `Unsupported(...)`, or `relationMode = "prisma"`. The error names the file and the line and suggests an edit to the Prisma ORM 7 schema. When that edit would also change the database on the next Prisma ORM 7 migration, the error says so. For example, removing an `Unsupported(...)` field drops its column, so for that field the error suggests adding `@@ignore` to the model instead, which leaves the next Prisma ORM 7 migration empty but removes the model from the Prisma ORM 7 client. Prisma ORM 8 has no views, so for a `view` block the error suggests removing the view or replacing it with a model over the table the view reads. `orm init --from-prisma7-schema` writes this config for you. + ## Emit-only config `contract emit` does not connect to a database, so the `orm` section can omit `db.connection`: diff --git a/apps/docs/content/docs/cli/contract-emit.mdx b/apps/docs/content/docs/cli/contract-emit.mdx index 4b07f20961..00d0a75f27 100644 --- a/apps/docs/content/docs/cli/contract-emit.mdx +++ b/apps/docs/content/docs/cli/contract-emit.mdx @@ -10,6 +10,8 @@ metaDescription: Learn how to emit contract.json and contract.d.ts for Prisma OR The command is offline. It does not need a database connection. +A Prisma schema source can be one `.prisma` file or a glob that matches several files; see [Split the schema across several files](/cli/configuration#split-the-schema-across-several-files). `contract emit` reads only the `.prisma` files whose first line is `// use prisma-8`, and skips any other file without a warning. When no file starts with that line, it fails with `CONTRACT.SOURCE_LOAD_FAILED` and reports the problem with the code `PSL_NO_OPTED_IN_SCHEMA_FILES`. + ## Usage ```npm @@ -31,7 +33,9 @@ The command emits: - `contract.json`, the canonical machine-readable contract - `contract.d.ts`, the generated TypeScript contract declarations -Do not edit these files by hand. Re-run `contract emit` after changing the contract source or extension pack list. +Do not edit these files by hand. Re-run `contract emit` after changing the contract source or extension pack list. The first emit after you upgrade to `8.0.0-rc.12` reorders the entries in `contract.d.ts` to follow the order in `contract.json`, which needs no change to your code. + +When the contract source cannot be read, the command fails with `CONTRACT.SOURCE_LOAD_FAILED` and prints each finding, meaning each problem it found in the source, with the file and line where it knows them. In `--json` output, the findings are the entries of the `envelope.diagnostics` array in the final `result` event, next to `envelope.error`. Each entry has a `code`, a `summary`, and, where known, `where.path` and `where.line`. If an entry's `code` is `CONTRACT.SOURCE_DIAGNOSTIC`, the code of the specific problem, such as `PSL_NO_OPTED_IN_SCHEMA_FILES`, is in its `meta.code`. ## Run it automatically diff --git a/apps/docs/content/docs/cli/contract-infer.mdx b/apps/docs/content/docs/cli/contract-infer.mdx index 0e267a98b4..7099108188 100644 --- a/apps/docs/content/docs/cli/contract-infer.mdx +++ b/apps/docs/content/docs/cli/contract-infer.mdx @@ -43,6 +43,12 @@ Inference gives you a starting point, not a finished design. Review: - defaults, indexes, and constraints - extension-backed column types +The file starts with `// use prisma-8`, because `contract emit` reads only `.prisma` files that start with that line. Each model is named after its table, and gets `@@map` only when the table name differs from the model name: a table `User` becomes `model User`, and a table `user_profile` becomes `model UserProfile` with `@@map("user_profile")`. + +Every column default is written in a form `contract emit` accepts, so you can emit the file without editing it. [Default values](/orm/contract-authoring/psl-syntax#default-values) shows those forms. A list column that allows `NULL` is written `Type[]?`, and a list column that is `NOT NULL` is written `Type[]`. + +If you keep an inferred contract in version control, running `contract infer` again after an upgrade can write the same database differently, so review the diff before you commit it. + The command stops at `contract.prisma`. Follow it with the emit and sign steps: ```npm diff --git a/apps/docs/content/docs/cli/db-verify.mdx b/apps/docs/content/docs/cli/db-verify.mdx index 852a919c98..eaebf0e349 100644 --- a/apps/docs/content/docs/cli/db-verify.mdx +++ b/apps/docs/content/docs/cli/db-verify.mdx @@ -60,3 +60,13 @@ npx prisma db verify --db "$DATABASE_URL" --json | Extension mismatch | The contract requires an extension that is not wired in the config. | Fix the database or contract, emit again if needed, then verify again. + +## How PostgreSQL defaults are compared + +When a column default is a literal value, `db verify` reads it as a value before it compares it with your contract, so the casts PostgreSQL adds when it prints the default do not cause a difference. This covers numbers such as `'-1'::integer` and `(5)::smallint`, text and enum values, including an enum value cast to a type in another PostgreSQL schema, `timestamp` values, `true`, `false`, `NULL`, JSON, and lists written as `'{...}'` or `ARRAY[...]`. `db verify` also recognizes `now()`, `clock_timestamp()`, `gen_random_uuid()`, and a sequence default, which it treats as `autoincrement()`. + +Any other default is a SQL expression, which you write in your contract as a `sql` default, such as ``@default(sql`(now() + '00:03:00'::interval)`)``. [Default values](/orm/contract-authoring/psl-syntax#default-values) shows how to write one. `db verify` cannot work out whether two SQL expressions give the same value, so it compares their text, ignoring letter case and spaces. PostgreSQL often rewrites an expression when it stores it, for example by adding casts, so write a `sql` default in your contract the way PostgreSQL stores it. To see that form, run `npx prisma contract infer --output ./inferred.prisma` and copy the column's `@default` from that file. + +Check constraints and the `WHERE` clause of a partial index are compared more strictly than `sql` defaults: their text must match exactly, including letter case and spaces. + +If `db verify` reports a difference in a `timestamptz` value inside a check constraint or a partial index's `WHERE` clause, check whether your contract was inferred before `8.0.0-rc.12` from a server that was not set to UTC. `db verify` reads the database with the time zone set to UTC and dates in ISO format, whatever the server or your database role sets, so a value that your contract has in another time zone no longer matches as text. To fix it, copy the new text from a fresh `npx prisma contract infer --output ./inferred.prisma` into your contract, emit the contract, and run `db sign`. diff --git a/apps/docs/content/docs/cli/global-flags.mdx b/apps/docs/content/docs/cli/global-flags.mdx index 1409297a7d..efd35ae1c9 100644 --- a/apps/docs/content/docs/cli/global-flags.mdx +++ b/apps/docs/content/docs/cli/global-flags.mdx @@ -18,7 +18,7 @@ All commands in the unified Prisma CLI accept these flags. | `--color` / `--no-color` | Force colored output on or off. | | `--interactive` / `--no-interactive` | Force prompts on or off. | | `-y`, `--yes` | Accept prompt defaults without asking. | -| `--confirm ` | Grant a consent prompt non-interactively by typing its token (repeatable). | +| `--confirm ` | Grant a consent prompt in advance by giving its token, so the command does not ask (repeatable). Works in scripts and in an interactive terminal. | | `--config ` | Read this config file instead of `./prisma.config.ts`. | | `-h`, `--help` | Print the manual for a command: what it does, its options, a workflow where one applies, and examples. | | `--version` | Print the CLI version and exit. | diff --git a/apps/docs/content/docs/cli/migration-new.mdx b/apps/docs/content/docs/cli/migration-new.mdx index 86b1d1c668..72826fdadb 100644 --- a/apps/docs/content/docs/cli/migration-new.mdx +++ b/apps/docs/content/docs/cli/migration-new.mdx @@ -21,10 +21,23 @@ npx prisma migration new --name split-name | Option | What it does | | --- | --- | | `--name ` | Sets the migration directory name suffix. | -| `--from ` | Sets the starting contract hash. Defaults to the latest migration target. | +| `--from ` | Starts from the contract state an existing migration ends at: the `to` hash in that migration's `migration.json`, or a unique prefix of it. Without it, see [Where it starts](#where-it-starts). | | `--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. + +## Where it starts + +Without `--from`, `migration new` picks its starting point the way [`migration plan`](/cli/migration-plan) does. The result depends on whether the [`db` ref](/cli/migration-ref#the-db-ref) exists and whether `migrations/app/` has migrations. The `db` ref is the file `migrations/app/refs/db.json`, which records the contract state you expect your local database to match. `migrations/app/` is the folder for your application's own migrations, and each extension package that ships migrations has its own folder beside it. + +- When the `db` ref exists and `migrations/app/` has migrations, it starts from the `db` ref. +- When there are no migrations and no `db` ref, it starts from an empty database. +- When migrations exist but there is no `db` ref, it refuses with `MIGRATION.PLAN_ORIGIN_UNKNOWN`. Pass `--from` with the `to` hash of the migration to build on, or point the `db` ref at the state your database is on. To find that state, run `npx prisma migration status --db "$DATABASE_URL" --json`: the `currentContract` of the `app` entry in `result.spaces` is the hash of the contract state your database matches. Then run `npx prisma migration ref set db `, where `` is that hash or the directory name of the migration that ends at it. +- When the `db` ref exists but there are no migrations, it refuses with `MIGRATION.HASH_NOT_IN_GRAPH`, because there is no migration yet that ends at the state the `db` ref names. Run `migration plan` first. It writes a [baseline migration](/orm/migrations/the-migration-graph#baselines), a migration from an empty database to that state, and then `migration new` can start from it. `migration plan` reads that state from the copy saved under `migrations/snapshots/` by the command that set the `db` ref, and if the copy is missing, it fails and asks you to restore `migrations/snapshots/` from version control. + +Before `8.0.0-rc.12`, `migration new` started from the newest migration. Scripts that relied on that should pass `--from` with the newest migration's `to` hash. + ## Examples ```npm diff --git a/apps/docs/content/docs/cli/migration-plan.mdx b/apps/docs/content/docs/cli/migration-plan.mdx index fbb7012412..9a95702243 100644 --- a/apps/docs/content/docs/cli/migration-plan.mdx +++ b/apps/docs/content/docs/cli/migration-plan.mdx @@ -19,7 +19,11 @@ Keep the `db` ref current and you never see the refusal. [`db init`](/cli/db-ini ### The automatic baseline -When `migrations/app/` is empty and the `db` ref points at a contract whose snapshot is stored under `migrations/snapshots/`, one `migration plan` run writes a baseline package from nothing to the ref's contract and, when your emitted contract differs from the ref's, a second package with the delta. Expect one or two new directories in `git status`. The baseline is never replayed against a database that already carries a marker, because the runner starts from the marker and only applies edges past it. +When `migrations/app/` is empty and the `db` ref points at a contract whose snapshot is stored under `migrations/snapshots/`, one `migration plan` run writes a baseline package from nothing to the ref's contract and, when your emitted contract differs from the ref's, a second package with the delta. Expect one or two new directories in `git status`. The baseline is never applied to a database that already has a marker, because `db migrate` starts from the marker and applies only the migrations after it. + +The baseline only creates things, because it is planned from an empty database, so it never removes data. The second package can: `migration plan` writes it without asking, and its output marks each destructive operation in it and warns that it may cause data loss. Review that package before you apply it. + +When the `db` ref points at a contract state that already has a migration starting from it, `migration plan` writes a second migration that starts from the same state, 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 does not update the `db` ref. `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, pass `--from` with that migration's directory name. The command is offline. It does not need a database connection. diff --git a/apps/docs/content/docs/cli/orm-init.mdx b/apps/docs/content/docs/cli/orm-init.mdx index ecdfd27346..9fceed4586 100644 --- a/apps/docs/content/docs/cli/orm-init.mdx +++ b/apps/docs/content/docs/cli/orm-init.mdx @@ -31,6 +31,7 @@ npx prisma@latest orm init --yes --target postgres --authoring psl | `--target ` | Sets the database target. Use `postgres` or `mongodb`. | | `--authoring