Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 8 additions & 3 deletions apps/docs/content/docs/orm/prisma-migrate/getting-started.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -155,13 +155,18 @@ To include [unsupported database features](/orm/prisma-migrate/workflows/unsuppo
- Open the `migration.sql` file generated in the [Create a baseline migration](#create-a-baseline-migration) section.
- Modify the generated SQL. For example:

- If the changes are minor, you can append additional custom SQL to the generated migration. The following example creates a partial index:
- If the changes are minor, you can append additional custom SQL to the generated migration. The following example creates a trigger function:

```sql title="migration.sql"
/* Generated migration SQL */

CREATE UNIQUE INDEX tests_success_constraint ON posts (subject, target) -- [!code ++]
WHERE success; -- [!code ++]
CREATE OR REPLACE FUNCTION notify_on_insert() -- [!code ++]
RETURNS TRIGGER AS $$ -- [!code ++]
BEGIN -- [!code ++]
PERFORM pg_notify('new_record', NEW.id::text); -- [!code ++]
RETURN NEW; -- [!code ++]
END; -- [!code ++]
$$ LANGUAGE plpgsql; -- [!code ++]
```

- If the changes are significant, it can be easier to replace the entire migration file with the result of a database dump:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ Sometimes, you need to modify a migration **before applying it**. For example:
- You want to introduce a significant refactor, such as changing blog post tags from a `String[]` to a `Tag[]`
- You want to [rename a field](/orm/prisma-migrate/workflows/customizing-migrations#example-rename-a-field) (by default, Prisma Migrate will drop the existing field)
- You want to [change the direction of a 1-1 relationship](/orm/prisma-migrate/workflows/customizing-migrations#example-change-the-direction-of-a-1-1-relation)
- You want to add features that cannot be represented in Prisma Schema Language - such as a partial index or a stored procedure.
- You want to add features that cannot be represented in Prisma Schema Language - such as a stored procedure or a trigger.

The `--create-only` command allows you to create a migration without applying it:

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ For type mappings organized by database provider, see:

## Handling unsupported database features

Prisma Migrate cannot automatically create database features that have no equivalent in Prisma Schema Language (PSL). For example, there is currently no way to define a stored procedure or a partial index in PSL. However, there are ways to add unsupported features to your database with Prisma Migrate:
Prisma Migrate cannot automatically create database features that have no equivalent in Prisma Schema Language (PSL). For example, there is currently no way to define a stored procedure or a trigger in PSL. However, there are ways to add unsupported features to your database with Prisma Migrate:

- [Handle unsupported field types](/orm/prisma-schema/data-model/unsupported-database-features#unsupported-field-types) (like `circle`)
- [Handle unsupported features](/orm/prisma-schema/data-model/unsupported-database-features#unsupported-database-features), like stored procedures
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,13 @@ Prisma Migrate uses the Prisma schema to determine what features to create in th
- Stored procedures
- Triggers
- Views
- Partial indexes

To add an unsupported feature to your database, you must [customize a migration](/orm/prisma-migrate/workflows/customizing-migrations) to include that feature before you apply it.

:::tip
The Prisma schema is able to represent [unsupported field types](/orm/prisma-schema/data-model/unsupported-database-features#unsupported-field-types) and [native database functions](/orm/prisma-migrate/workflows/native-database-functions).
Partial indexes are now supported in Prisma Schema Language via the `where` argument on `@@index`, `@@unique`, and `@unique`. See [Configuring partial indexes](/orm/prisma-schema/data-model/indexes#configuring-partial-indexes-with-where) for details. You no longer need to customize migrations for partial indexes.

The Prisma schema is also able to represent [unsupported field types](/orm/prisma-schema/data-model/unsupported-database-features#unsupported-field-types) and [native database functions](/orm/prisma-migrate/workflows/native-database-functions).
:::

:::warning
Expand All @@ -34,12 +35,16 @@ To customize a migration to include an unsupported feature:
npx prisma migrate dev --create-only
```

- Open the generated `migration.sql` file and add the unsupported feature - for example, a partial index:
- Open the generated `migration.sql` file and add the unsupported feature - for example, a trigger function:

```sql title="migration.sql"
CREATE UNIQUE INDEX tests_success_constraint
ON posts (subject, target)
WHERE success;
CREATE OR REPLACE FUNCTION notify_on_insert()
RETURNS TRIGGER AS $$
BEGIN
PERFORM pg_notify('new_record', NEW.id::text);
RETURN NEW;
END;
$$ LANGUAGE plpgsql;
```

- Apply the migration:
Expand Down
161 changes: 161 additions & 0 deletions apps/docs/content/docs/orm/prisma-schema/data-model/indexes.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -494,6 +494,167 @@ model Post {
}
```

### Configuring partial indexes with `where`

The `where` argument allows you to define [partial indexes](https://www.postgresql.org/docs/current/indexes-partial.html) (also known as filtered indexes). A partial index only includes rows that match a specified condition, which reduces the index size and improves both write performance and query performance for the indexed subset of data.

The `where` argument is available on the `@unique`, `@@unique` and `@@index` attributes. It requires the `partialIndexes` Preview feature.

:::note

Partial indexes are supported on **PostgreSQL**, **SQLite**, **SQL Server**, and **CockroachDB**. They are **not** supported on MySQL.

:::

#### Enabling the `partialIndexes` Preview feature

To use partial indexes, add the `partialIndexes` feature flag to the `generator` block of your `schema.prisma` file:

```prisma title="schema.prisma" showLineNumbers
generator client {
provider = "prisma-client"
output = "./generated"
previewFeatures = ["partialIndexes"]
}
```

#### Raw SQL syntax with `raw()`

You can define a partial index with a raw SQL predicate string using the `raw()` function. This approach supports any valid SQL `WHERE` expression that your database accepts:

```prisma title="schema.prisma" showLineNumbers
model User {
id Int @id
email String
status String
deletedAt DateTime?

@@unique([email], where: raw("status = 'active'"))
@@index([email], where: raw("\"deletedAt\" IS NULL"))
}
```

This generates SQL like:

**PostgreSQL:**

```sql
CREATE UNIQUE INDEX "User_email_key" ON "User" ("email") WHERE (status = 'active');
CREATE INDEX "User_email_idx" ON "User" ("email") WHERE ("deletedAt" IS NULL);
```

**SQLite:**

```sql
CREATE UNIQUE INDEX "User_email_key" ON "User" ("email") WHERE status = 'active';
CREATE INDEX "User_email_idx" ON "User" ("email") WHERE "deletedAt" IS NULL;
```

**SQL Server:**

```sql
CREATE UNIQUE NONCLUSTERED INDEX [User_email_key] ON [dbo].[User]([email]) WHERE ([status]='active');
CREATE NONCLUSTERED INDEX [User_email_idx] ON [dbo].[User]([email]) WHERE ([deletedAt] IS NULL);
```

The `raw()` syntax can be used with any SQL expression your database supports, making it the most flexible option.

#### Object literal syntax (type-safe alternative)

You can also define partial indexes using an object literal syntax, which provides type-safety by validating field names and value types against your Prisma schema:

```prisma title="schema.prisma" showLineNumbers
model Post {
id Int @id
title String
published Boolean

@@index([title], where: { published: true })
@@unique([title], where: { published: true })
}
```

The object literal syntax supports the following value types:

| Value type | Example | Notes |
| ---------------- | ---------------------------------------- | ------------------------------------------------------ |
| `Boolean` | `{ active: true }`, `{ deleted: false }` | For `Boolean` fields |
| `String` | `{ status: "active" }` | For `String`, `DateTime`, and `Enum` fields |
| `Number` | `{ priority: 1 }`, `{ score: 1.5 }` | For `Int`, `BigInt`, `Float`, and `Decimal` fields |
| `null` | `{ deletedAt: null }` | Translates to `IS NULL`. Works with any nullable field |
| `{ not: value }` | `{ deletedAt: { not: null } }` | Negation. Translates to `IS NOT NULL` or `!= value` |

You can combine multiple conditions in a single object:

```prisma title="schema.prisma" showLineNumbers
model User {
id Int @id
email String
active Boolean
deletedAt DateTime?

@@unique([email], where: { active: true, deletedAt: null })
}
```

:::note

The object literal syntax validates field types. For example, you cannot use a `Boolean` value for a `String` field. For fields with types that are not supported by the object syntax (such as `Unsupported` or composite types), use `raw()` instead.

:::

#### Using `where` with other index arguments

The `where` argument can be combined with other index arguments such as `name` and `map`:

```prisma title="schema.prisma" showLineNumbers
model User {
id Int @id
email String
status String

@@unique([email], name: "email_active_unique", map: "idx_email_active", where: raw("status = 'active'"))
}
```

#### Database-specific behavior

| Database | Migrations | Introspection | Notes |
| ----------- | ------------- | ------------- | ---------------------------------------------------------------------- |
| PostgreSQL | Full support | Full support | Full predicate support |
| SQLite | Full support | Full support | Full predicate support |
| SQL Server | Full support | Full support | Filtered indexes via `CREATE INDEX` |
| CockroachDB | Create only | Not supported | Cannot introspect predicate text; predicate modifications not detected |
| MySQL | Not supported | Not supported | Partial indexes are not supported by the database |

:::warning

**CockroachDB limitation**: CockroachDB supports creating partial indexes, but it cannot introspect the predicate text from existing indexes. This means that after initial creation, modifications to the `where` clause (adding, changing, or removing a predicate) will not be detected by Prisma Migrate. The differ skips predicate comparison for CockroachDB to prevent false-positive migrations.

:::

#### Introspection

When you run `prisma db pull` on a database that contains partial indexes, Prisma ORM will:

1. Automatically add `"partialIndexes"` to the `previewFeatures` list in your generator block
2. Represent the partial index predicate using the `raw()` syntax with the database's normalized form of the SQL expression

For example, a PostgreSQL partial unique index on a single field will be introspected as:

```prisma title="schema.prisma" showLineNumbers
model User {
id Int @id
email String @unique(where: raw("(status = 'active'::text)"))
status String
}
```

:::note

The introspected `raw()` string reflects the database's normalized form of the SQL expression, which may differ from what you originally wrote. For example, PostgreSQL adds parentheses and explicit type casts (e.g., `'active'::text`), SQL Server wraps column names in brackets and adds parentheses (e.g., `([status]='active')`), while SQLite generally preserves the original expression as-is.

:::

## Full text indexes (MySQL and MongoDB)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -79,4 +79,10 @@ The `prisma migrate dev` and `prisma db push` command will both create a `positi

## Unsupported database features

Some features, like SQL views or partial indexes, cannot be represented in the Prisma schema. If your project uses [Prisma Migrate](/orm/prisma-migrate), you must [include unsupported features as part of a migration](/orm/prisma-migrate/workflows/unsupported-database-features) .
Some features, like SQL views, cannot be represented in the Prisma schema. If your project uses [Prisma Migrate](/orm/prisma-migrate), you must [include unsupported features as part of a migration](/orm/prisma-migrate/workflows/unsupported-database-features) .

:::tip

Partial indexes are now supported in Prisma Schema Language via the `where` argument on `@@index`, `@@unique`, and `@unique`. See [Configuring partial indexes](/orm/prisma-schema/data-model/indexes#configuring-partial-indexes-with-where) for details.

:::
2 changes: 1 addition & 1 deletion apps/docs/content/docs/orm/reference/database-features.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ These features are _only_ for relational databases. Supported features for NoSQL
| -------------- | :--------------------------------------: | :---------------------------------------------------------------------------------------------------------: | :-----------: | :------------: |
| `UNIQUE` | ✔️ | [`@unique` and `@@unique`](/orm/prisma-schema/data-model/models#defining-a-unique-field) | ✔️ | ✔️ |
| `USING` | PostgreSQL only | [`type`](/orm/prisma-schema/data-model/indexes#configuring-the-access-type-of-indexes-with-type-postgresql) | ✔️ | ✔️ |
| `WHERE` | ✔️ | Not yet | ✔️ | Not yet |
| `WHERE` | ✔️ | [`where`](/orm/prisma-schema/data-model/indexes#configuring-partial-indexes-with-where) (Preview) | ✔️ | ✔️ |
| `(expression)` | ✔️ | Not yet | ✔️ | Not yet |
| `INCLUDE` | PostgreSQL and Microsoft SQL Server only | Not yet | ✔️ | Not yet |

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ The following [Preview](/orm/more/releases#preview) feature flags are available
| `strictUndefinedChecks` | [5.20.0](https://github.com/prisma/prisma/releases/tag/5.20.0) | [Submit feedback](https://github.com/prisma/prisma/discussions/25271) |
| [`fullTextSearchPostgres`](/v6/orm/prisma-client/queries/full-text-search) | [6.0.0](https://github.com/prisma/prisma/releases/tag/6.0.0) | [Submit feedback](https://github.com/prisma/prisma/issues/25773) |
| `shardKeys` | [6.10.0](https://pris.ly/release/6.10.0) | [Submit feedback](https://github.com/prisma/prisma/issues/) |
| [`partialIndexes`](/orm/prisma-schema/data-model/indexes) | [7.4.0](https://pris.ly/release/7.4.0) | [Submit feedback](https://github.com/prisma/prisma/issues/6974) |

To enable a Preview feature, [add the feature flag to the `generator` block](#enabling-a-prisma-client-preview-feature) in your `schema.prisma` file. [Share your feedback on all Preview features on GitHub](https://github.com/prisma/prisma/issues/3108).

Expand Down
Loading
Loading