apps/docs/content/docs/orm/reference/prisma-client-reference.mdx
The Prisma Client API reference documentation is based on the following schema:
model User {
id Int @id @default(autoincrement())
name String?
email String @unique
profileViews Int @default(0)
role Role @default(USER)
coinflips Boolean[]
posts Post[]
city String
country String
profile ExtendedProfile?
pets Json
}
model ExtendedProfile {
id Int @id @default(autoincrement())
userId Int? @unique
bio String?
User User? @relation(fields: [userId], references: [id])
}
model Post {
id Int @id @default(autoincrement())
title String
published Boolean @default(true)
author User @relation(fields: [authorId], references: [id])
authorId Int
comments Json
views Int @default(0)
likes Int @default(0)
}
enum Role {
USER
ADMIN
}
All example generated types (such as UserSelect and UserWhereUniqueInput) are based on the User model.
PrismaClientThis section describes the PrismaClient constructor and its parameters.
adapterSpecifies a driver adapter for database connections. Required unless using accelerateUrl.
import { PrismaPg } from "@prisma/adapter-pg";
import { PrismaClient } from "../prisma/generated/client";
const adapter = new PrismaPg({ connectionString: process.env.DATABASE_URL });
const prisma = new PrismaClient({ adapter });
accelerateUrlSpecifies a Prisma Accelerate URL for remote query execution. Required unless using adapter.
import { PrismaClient } from "../prisma/generated/client";
const prisma = new PrismaClient({
accelerateUrl: process.env.ACCELERATE_URL,
});
logDetermines the type and level of logging. See also: Logging
| Option | Example |
|---|---|
| Array of log levels | [ "info", "query" ] |
| Array of log definitions | [ { level: "info", emit: "event" }, { level: "warn", emit: "stdout" }] |
| Name | Example |
|---|---|
query | Logs all queries run by Prisma. |
For relational databases this logs all SQL queries. Example:
prisma:query SELECT "public"."User"."id", "public"."User"."email" FROM "public"."User" WHERE ("public"."User"."id") IN (SELECT "t0"."id" FROM "public"."User" AS "t0" INNER JOIN "public"."Post" AS "j0" ON ("j0"."authorId") = ("t0"."id") WHERE ("j0"."views" > $1 AND "t0"."id" IS NOT NULL)) OFFSET $2
For MongoDB this logs queries using the mongosh shell format. Example:
prisma:query db.User.deleteMany({ _id: ( $in: [ “6221ce49f756b0721fc00542”, ], }, }) |
| info | Example:
prisma:info Started http server on http://127.0.0.1:58471 |
| warn | Warnings. |
| error | Errors. |
| Name | Description |
|---|---|
stdout | See: stdout |
event | Raises an event that you can subscribe to. |
The query event type:
export type QueryEvent = {
timestamp: Date;
query: string; // Query sent to the database
params: string; // Query parameters
duration: number; // Time elapsed (in milliseconds) between client issuing query and database responding - not only time taken to run query
target: string;
};
Note that for MongoDB, the params and duration fields will be undefined.
All other log level event types:
export type LogEvent = {
timestamp: Date;
message: string;
target: string;
};
query and info to stdoutimport { PrismaClient } from "../prisma/generated/client";
const prisma = new PrismaClient({ log: ["query", "info"] });
async function main() {
const countUsers = await prisma.user.count({});
}
main()
.then(async () => {
await prisma.$disconnect();
})
.catch(async (e) => {
console.error(e);
await prisma.$disconnect();
process.exit(1);
});
prisma:info Starting a postgresql pool with 13 connections.
prisma:info Started http server
prisma:query SELECT COUNT(*) FROM (SELECT "public"."User"."id" FROM "public"."User" WHERE 1=1 ORDER BY "public"."User"."coinflips" ASC OFFSET $1) AS "sub"
query event to consoleimport { PrismaClient } from "../prisma/generated/client";
const prisma = new PrismaClient({
log: [{ level: "query", emit: "event" }],
});
prisma.$on("query", (e) => {
console.log(e);
});
async function main() {
const countUsers = await prisma.user.count({});
}
main()
.then(async () => {
await prisma.$disconnect();
})
.catch(async (e) => {
console.error(e);
await prisma.$disconnect();
process.exit(1);
});
{
timestamp: 2020-11-17T10:32:10.898Z,
query: 'SELECT COUNT(*) FROM (SELECT "public"."User"."id" FROM "public"."User" WHERE 1=1 OFFSET $1) AS "sub"',
params: '[0]',
duration: 5,
target: 'quaint::connector::metrics'
}
info, warn, and error events to consoleimport { PrismaClient } from "../prisma/generated/client";
const prisma = new PrismaClient({
log: [
{ level: "warn", emit: "event" },
{ level: "info", emit: "event" },
{ level: "error", emit: "event" },
],
});
prisma.$on("warn", (e) => {
console.log(e);
});
prisma.$on("info", (e) => {
console.log(e);
});
prisma.$on("error", (e) => {
console.log(e);
});
async function main() {
const countUsers = await prisma.user.count({});
}
main()
.then(async () => {
await prisma.$disconnect();
})
.catch(async (e) => {
console.error(e);
await prisma.$disconnect();
process.exit(1);
});
{
timestamp: 2020-11-17T10:33:24.592Z,
message: 'Starting a postgresql pool with 13 connections.',
target: 'quaint::pooled'
}
{
timestamp: 2020-11-17T10:33:24.637Z,
message: 'Started http server',
target: 'query_engine::server'
}
errorFormatDetermines the level and formatting of errors returned by Prisma Client.
| Name | Description |
|---|---|
undefined | If it's not defined, the default is colorless. |
pretty | Enables pretty error formatting. |
colorless (default) | Enables colorless error formatting. |
minimal | Enables minimal error formatting. |
const prisma = new PrismaClient({
// Defaults to colorless
});
pretty error formattingconst prisma = new PrismaClient({
errorFormat: "pretty",
});
colorless error formattingconst prisma = new PrismaClient({
errorFormat: "colorless",
});
minimal error formattingconst prisma = new PrismaClient({
errorFormat: "minimal",
});
commentsDefines an array of SQL commenter plugins that add metadata to your SQL queries as comments. This is useful for observability, debugging, and correlating queries with application traces.
| Option | Description |
|---|---|
SqlCommenterPlugin[] | An array of SQL commenter plugin functions. Each plugin receives query context and returns key-value pairs. |
| Package | Description |
|---|---|
@prisma/sqlcommenter-query-tags | Adds arbitrary tags to queries within an async context using AsyncLocalStorage |
@prisma/sqlcommenter-trace-context | Adds W3C Trace Context (traceparent) headers for distributed tracing |
import { PrismaClient } from "../prisma/generated/client";
import { PrismaPg } from "@prisma/adapter-pg";
import { queryTags } from "@prisma/sqlcommenter-query-tags";
import { traceContext } from "@prisma/sqlcommenter-trace-context";
const adapter = new PrismaPg({ connectionString: process.env.DATABASE_URL });
const prisma = new PrismaClient({
adapter,
comments: [queryTags(), traceContext()],
});
import { PrismaClient } from "../prisma/generated/client";
import { PrismaPg } from "@prisma/adapter-pg";
import type { SqlCommenterPlugin } from "@prisma/sqlcommenter";
const appPlugin: SqlCommenterPlugin = (context) => ({
application: "my-app",
environment: process.env.NODE_ENV ?? "development",
model: context.query.modelName,
action: context.query.action,
});
const adapter = new PrismaPg({ connectionString: process.env.DATABASE_URL });
const prisma = new PrismaClient({
adapter,
comments: [appPlugin],
});
This produces SQL queries with comments like:
SELECT "id", "name" FROM "User" /*action='findMany',application='my-app',environment='production',model='User'*/
For more details, see SQL comments.
transactionOptionsSets default transaction options globally.
| Option | Description |
|---|---|
maxWait | The maximum amount of time Prisma Client will wait to acquire a transaction from the database. The default value is 2 seconds. |
timeout | The maximum amount of time the interactive transaction can run before being canceled and rolled back. The default value is 5 seconds. |
isolationLevel | Sets the transaction isolation level. By default this is set to the value currently configured in your database. The available levels can vary depending on the database you use. |
const prisma = new PrismaClient({
transactionOptions: {
isolationLevel: Prisma.TransactionIsolationLevel.Serializable,
maxWait: 5000, // default: 2000
timeout: 10000, // default: 5000
},
});
Use model queries to perform CRUD operations on your models. See also: CRUD
findUnique()findUnique() query lets you retrieve a single database record:
findUnique() queries with the same select and where parameters.findUniqueOrThrow instead.equals, contains, not) to filter fields of the JSON data type. Using filter conditions will likely result in a null response for that field.| Name | Example type (User) | Required | Description |
|---|---|---|---|
where | UserWhereUniqueInput | Yes | Wraps all fields of a model so that a record can be selected (learn more). |
select | XOR<UserSelect, null> | No | Specifies which properties to include on the returned object. |
include | XOR<UserInclude, null> | No | Specifies which relations should be eagerly loaded on the returned object. |
omit | XOR<UserOmit, null> | No | Specifies which properties to exclude on the returned object. Excludes specified fields from the result |
relationLoadStrategy | 'join' or 'query' | No | Default: join. Load strategy for relations. Requires relationJoins preview feature. |
| Return type | Example | Description |
|---|---|---|
| JavaScript object (typed) | User | |
| JavaScript object (plain) | { title: "Hello world" } | Use select and include to determine which fields to return. |
null | null | Record not found |
User record with an id of 42const result = await prisma.user.findUnique({
where: {
id: 42,
},
});
User record with an email of [email protected]const result = await prisma.user.findUnique({
where: {
email: "[email protected]",
},
});
User record with firstName of Alice and lastName of Smith (@@unique)model User {
firstName String
lastName String
@@unique(fields: [firstName, lastName], name: "fullname")
}
const result = await prisma.user.findUnique({
where: {
fullname: {
// name property of @@unique attribute - default is firstname_lastname
firstName: "Alice",
lastName: "Smith",
},
},
});
User record with firstName of Alice and lastName of Smith (@@id)model User {
firstName String
lastName String
@@id([firstName, lastName])
}
const result = await prisma.user.findUnique({
where: {
firstName_lastName: {
firstName: "Alice",
lastName: "Smith",
},
},
});
findUniqueOrThrow()findUniqueOrThrow() retrieves a single record in the same way as findUnique(). However, if the query does not find the requested record, it throws a PrismaClientKnownRequestError.
Here's an example of its usage:
await prisma.user.findUniqueOrThrow({
where: { id: 1 },
});
findUniqueOrThrow() differs from findUnique() as follows:
Its return type is non-nullable. For example, post.findUnique() can return post or null, but post.findUniqueOrThrow() always returns post.
It is not compatible with sequential operations in the $transaction API. If the query throws a PrismaClientKnownRequestError, then the API will not roll back any operations in the array of calls. As a workaround, you can use interactive transactions with the $transaction API, as follows:
$transaction(async (prisma) => {
await prisma.model.create({ data: { ... });
await prisma.model.findUniqueOrThrow();
})
findFirst()findFirst returns the first record in a list that matches your criteria.
findFirstOrThrow instead.| Name | Example type (User) | Required | Description |
|---|---|---|---|
select | XOR<UserSelect, null> | No | Specifies which properties to include on the returned object. |
include | XOR<UserInclude, null> | No | Specifies which relations should be eagerly loaded on the returned object. |
omit | XOR<UserOmit, null> | No | Specifies which properties to exclude on the returned object. Excludes specified fields from the result. |
relationLoadStrategy | 'join' or 'query' | No | Default: join. Load strategy for relations. Requires relationJoins preview feature. |
where | UserWhereInput | No | Wraps all model fields in a type so that the list can be filtered by any property. |
orderBy | XOR<Enumerable<UserOrderByInput>, UserOrderByInput> | No | Lets you order the returned list by any property. |
| Return type | Example | Description |
|---|---|---|
| JavaScript object (typed) | User | Specifies which properties to include on the returned object. |
| JavaScript object (plain) | { title: "Hello world" } | Use select and include to determine which fields to return. |
null | null | Record not found |
findFirst calls findMany behind the scenes and accepts the same query options.take value when you use a findFirst query reverses the order of the list.See Filter conditions and operators for examples of how to filter results.
User record where the name is Aliceconst user = await prisma.user.findFirst({
where: { name: "Alice" },
});
Post record where the title starts with A test, reverse the list with takeimport { PrismaClient } from "../prisma/generated/client";
const prisma = new PrismaClient({});
async function main() {
const a = await prisma.post.create({
data: {
title: "A test 1",
},
});
const b = await prisma.post.create({
data: {
title: "A test 2",
},
});
const c = await prisma.post.findFirst({
where: {
title: {
startsWith: "A test",
},
},
orderBy: {
title: "asc",
},
take: -1, // Reverse the list
});
}
main();
findFirstOrThrow()findFirstOrThrow() retrieves a single data record in the same way as findFirst(). However, if the query does not find a record, it throws a PrismaClientKnownRequestError.
findFirstOrThrow() differs from findFirst() as follows:
Its return type is non-nullable. For example, post.findFirst() can return post or null, but post.findFirstOrThrow always returns post.
It is not compatible with sequential operations in the $transaction API. If the query returns PrismaClientKnownRequestError, then the API will not roll back any operations in the array of calls. As a workaround, you can use interactive transactions with the $transaction API, as follows:
prisma.$transaction(async (tx) => {
await tx.model.create({ data: { ... });
await tx.model.findFirstOrThrow();
})
findMany()findMany returns a list of records.
| Name | Type | Required | Description |
|---|---|---|---|
select | XOR<PostSelect, null> | No | Specifies which properties to include on the returned object. |
include | XOR<PostInclude, null> | No | Specifies which relations should be eagerly loaded on the returned object. |
omit | XOR<PostOmit, null> | No | Specifies which properties to exclude on the returned object. Excludes specified fields from the result |
relationLoadStrategy | 'join' or 'query' | No | Default: join. Load strategy for relations. Requires relationJoins preview feature. |
where | UserWhereInput | No | Wraps all model fields in a type so that the list can be filtered by any property. |
orderBy | XOR<Enumerable<PostOrder | ||
ByInput>, PostOrderByInput> | No | Lets you order the returned list by any property. | |
cursor | UserWhereUniqueInput | No | Specifies the position for the list (the value typically specifies an id or another unique value). |
take | number | No | Specifies how many objects should be returned in the list (as seen from the beginning (positive value) or end (negative value) either of the list or from the cursor position if mentioned) |
skip | number | No | Specifies how many of the returned objects in the list should be skipped. |
distinct | Enumerable<UserDistinctFieldEnum> | No | Lets you filter out duplicate rows by a specific field - for example, return only distinct Post titles. |
| Return type | Example | Description |
|---|---|---|
| JavaScript array object (typed) | User[] | |
| JavaScript array object (plain) | [{ title: "Hello world" }] | Use select and include to determine which fields to return. |
| Empty array | [] | No matching records found. |
See Filter conditions and operators for examples of how to filter results.
User records where the name is Aliceconst user = await prisma.user.findMany({
where: { name: "Alice" },
});
create()create creates a new database record.
| Name | Type | Required | Description |
|---|---|---|---|
data | XOR<UserCreateInput, | ||
UserUncheckedCreateInput> | Yes | Wraps all the model fields in a type so that they can be provided when creating new records. It also includes relation fields which lets you perform (transactional) nested inserts. Fields that are marked as optional or have default values in the datamodel are optional. | |
select | XOR<UserSelect, null> | No | Specifies which properties to include on the returned object. |
include | XOR<UserInclude, null> | No | Specifies which relations should be eagerly loaded on the returned object. |
omit | XOR<UserOmit, null> | No | Specifies which properties to exclude on the returned object. Excludes specified fields from the result |
relationLoadStrategy | 'join' or 'query' | No | Default: join. Load strategy for relations. Requires relationJoins preview feature. |
| Return type | Example | Description |
|---|---|---|
| JavaScript object (typed) | User | |
| JavaScript object (plain) | { name: "Alice Wonderland" } | Use select and include to determine which fields to return. |
create - for example, add a User and two Post records at the same time.emailconst user = await prisma.user.create({
data: { email: "[email protected]" },
});
In most cases, you can carry out batch inserts with the createMany() or createManyAndReturn() queries. However, there are scenarios where create() is the best option to insert multiple records.
The following example results in two INSERT statements:
import { Prisma, PrismaClient } from "../prisma/generated/client";
const prisma = new PrismaClient({ log: ["query"] });
async function main() {
let users: Prisma.UserCreateInput[] = [
{
email: "[email protected]",
name: "Ari",
profileViews: 20,
coinflips: [true, false, false],
role: "ADMIN",
},
{
email: "[email protected]",
name: "Elsa",
profileViews: 20,
coinflips: [true, false, false],
role: "ADMIN",
},
];
await Promise.all(
users.map(async (user) => {
await prisma.user.create({
data: user,
});
}),
);
}
main()
.then(async () => {
await prisma.$disconnect();
})
.catch(async (e) => {
console.error(e);
await prisma.$disconnect();
process.exit(1);
});
prisma:query BEGIN
prisma:query INSERT INTO "public"."User" ("name","email","profileViews","role","coinflips") VALUES ($1,$2,$3,$4,$5) RETURNING "public"."User"."id"
prisma:query SELECT "public"."User"."id", "public"."User"."name", "public"."User"."email", "public"."User"."profileViews", "public"."User"."role", "public"."User"."coinflips" FROM "public"."User" WHERE "public"."User"."id" = $1 LIMIT $2 OFFSET $3
prisma:query INSERT INTO "public"."User" ("name","email","profileViews","role","coinflips") VALUES ($1,$2,$3,$4,$5) RETURNING "public"."User"."id"
prisma:query COMMIT
prisma:query SELECT "public"."User"."id", "public"."User"."name", "public"."User"."email", "public"."User"."profileViews", "public"."User"."role", "public"."User"."coinflips" FROM "public"."User" WHERE "public"."User"."id" = $1 LIMIT $2 OFFSET $3
prisma:query COMMIT
update()update updates an existing database record.
| Name | Type | Required | Description |
|---|---|---|---|
data | XOR<UserUpdateInput | ||
UserUncheckedUpdateInput> | Yes | Wraps all the fields of the model so that they can be provided when updating an existing record. Fields that are marked as optional or have default values in the datamodel are optional. | |
where | UserWhereUniqueInput | Yes | Wraps all fields of a model so that a record can be selected (learn more). |
select | XOR<UserSelect, null> | No | Specifies which properties to include on the returned object. |
include | XOR<UserInclude, null> | No | Specifies which relations should be eagerly loaded on the returned object. |
omit | XOR<UserOmit, null> | No | Specifies which properties to exclude on the returned object. Excludes specified fields from the result. |
relationLoadStrategy | 'join' or 'query' | No | Default: join. Load strategy for relations. Requires relationJoins preview feature. |
| Return type | Example | Description |
|---|---|---|
| JavaScript object (typed) | User | |
| JavaScript object (plain) | { name: "Alice Wonderland" } | Use select and include to determine which fields to return. |
PrismaClientKnownRequestError (code P2025) | Thrown if the record to update does not exist. See Error reference |
update - for example, update a user and that user's posts at the same time.email of the User record with id of 1 to [email protected]const user = await prisma.user.update({
where: { id: 1 },
data: { email: "[email protected]" },
});
upsert():::info
This section covers the usage of the upsert() operation. To learn about using nested upsert queries within update(), reference the linked documentation.
:::
upsert does the following:
where condition, it updates that recordwhere condition, it creates a new database record| Name | Type | Required | Description |
|---|---|---|---|
create | XOR<UserCreateInput, | ||
UserUncheckedCreateInput> | Yes | Wraps all the fields of the model so that they can be provided when creating new records. It also includes relation fields which lets you perform (transactional) nested inserts. Fields that are marked as optional or have default values in the datamodel are optional. | |
update | XOR<UserUpdateInput, | ||
UserUncheckedUpdateInput> | Yes | Wraps all the fields of the model so that they can be provided when updating an existing record. Fields that are marked as optional or have default values in the datamodel are optional. | |
where | UserWhereUniqueInput | Yes | Wraps all fields of a model so that a record can be selected (learn more). |
select | XOR<UserSelect, null> | No | Specifies which properties to include on the returned object. |
include | XOR<UserInclude, null> | No | Specifies which relations should be eagerly loaded on the returned object. |
omit | XOR<UserOmit, null> | No | Specifies which properties to exclude on the returned object. Excludes specified fields from the result |
relationLoadStrategy | 'join' or 'query' | No | Default: join. Load strategy for relations. Requires relationJoins preview feature. |
| Return type | Example | Description |
|---|---|---|
| JavaScript object (typed) | User | |
| JavaScript object (plain) | { name: "Alice Wonderland" } | Use select and include to determine which fields to return. |
User record with an email of [email protected]const user = await prisma.user.upsert({
where: { id: 1 },
update: { email: "[email protected]" },
create: { email: "[email protected]" },
});
If multiple upsert operations happen at the same time and the record doesn't already exist, then one or more of the operations might return a unique key constraint error.
When Prisma Client does an upsert, it first checks whether that record already exists in the database. To make this check, Prisma Client performs a read operation with the where clause from the upsert operation. This has two possible outcomes, as follows:
When your application tries to perform two or more concurrent upsert operations, then a race condition might happen where two or more operations do not find the record and therefore try to create that record. In this situation, one of the operations successfully creates the new record but the other operations fail and return a unique key constraint error.
Handle the P2002 error in your application code. When it occurs, retry the upsert operation to update the row.
Where possible, Prisma Client hands over an upsert query to the database. This is called a database upsert.
Database upserts have the following advantages:
Prisma Client uses a database upsert automatically when specific criteria are met. When these criteria are not met, Prisma Client handles the upsert.
To use a database upsert, Prisma Client sends the SQL construction INSERT ... ON CONFLICT SET .. WHERE to the database.
Prisma Client uses database upserts with CockroachDB, PostgreSQL, or SQLite data sources.
Prisma Client uses a database upsert for an upsert query when the query meets the following criteria:
upsert's create and update optionsupsert's where optionwhere option and the unique field in the create option have the same valueIf your query does not meet these criteria, then Prisma Client handles the upsert itself.
The following examples use this schema:
model User {
id Int @id
profileViews Int
userName String @unique
email String
@@unique([id, profileViews])
}
The following upsert query meets all of the criteria, so Prisma Client uses a database upsert.
prisma.user.upsert({
where: {
userName: "Alice",
},
create: {
id: 1,
profileViews: 1,
userName: "Alice",
email: "[email protected]",
},
update: {
email: "[email protected]",
},
});
In this situation, Prisma uses the following SQL query:
INSERT INTO "public"."User" ("id","profileViews","userName","email") VALUES ($1,$2,$3,$4)
ON CONFLICT ("userName") DO UPDATE
SET "email" = $5 WHERE ("public"."User"."userName" = $6 AND 1=1) RETURNING "public"."User"."id", "public"."User"."profileViews", "public"."User"."userName", "public"."User"."email"
The following query has multiple unique values in the where clause, so Prisma Client does not use a database upsert:
prisma.User.upsert({
where: {
userName: "Alice",
profileViews: 1,
id: 1,
},
create: {
id: 1,
profileViews: 1,
userName: "Alice",
email: "[email protected]",
},
update: {
email: "[email protected]",
},
});
In the following query, the values for userName in the where and create options are different, so Prisma Client does not use a database upsert.
prisma.User.upsert({
where: {
userName: "Alice",
},
create: {
id: 1,
profileViews: 1,
userName: "AliceS",
email: "[email protected]",
},
update: {
email: "[email protected]",
},
});
In the following query, the selection on the title field in posts is a nested read, so Prisma Client does not use a database upsert.
prisma.user.upsert({
select: {
email: true,
id: true,
posts: {
select: {
title: true,
},
},
},
where: {
userName: "Alice",
},
create: {
id: 1,
profileViews: 1,
userName: "Alice",
email: "[email protected]",
},
update: {
email: "[email protected]",
},
});
delete()delete deletes an existing database record. You can delete a record:
To delete records that match a certain criteria, use deleteMany with a filter.
| Name | Type | Required | Description |
|---|---|---|---|
where | UserWhereUniqueInput | Yes | Wraps all fields of a model so that a record can be selected (learn more). |
select | XOR<UserSelect, null> | No | Specifies which properties to include on the returned object. |
include | XOR<UserInclude, null> | No | Specifies which relations should be eagerly loaded on the returned object. |
omit | XOR<UserOmit, null> | No | Specifies which properties to exclude on the returned object. Excludes specified fields from the result |
relationLoadStrategy | 'join' or 'query' | No | Default: join. Load strategy for relations. Requires relationJoins preview feature. |
| Return type | Example | Description |
|---|---|---|
| JavaScript object (typed) | User | The User record that was deleted. |
| JavaScript object (plain) | { name: "Alice Wonderland" } | Data from the User record that was deleted. Use select and include to determine which fields to return. |
PrismaClientKnownRequestError (code P2025) | Thrown if the record to delete does not exist. See Error reference |
User records with a prisma.io email address, use deleteMany)User record with an id of 1const user = await prisma.user.delete({
where: { id: 1 },
});
User record where email equals [email protected]The following query deletes a specific user record and uses select to return the name and email of the deleted user:
const deleteUser = await prisma.user.delete({
where: {
email: "[email protected]",
},
select: {
email: true,
name: true,
},
});
{ "email": "[email protected]", "name": "Elsa" }
createMany()createMany creates multiple records in a transaction.
| Name | Type | Required | Description |
|---|---|---|---|
data | Enumerable<UserCreateManyInput> | Yes | Wraps all the model fields in a type so that they can be provided when creating new records. Fields that are marked as optional or have default values in the datamodel are optional. |
skipDuplicates? | boolean | No | Do not insert records with unique fields or ID fields that already exist. Only supported by databases that support ON CONFLICT DO NOTHING. This excludes MongoDB and SQLServer |
| Return type | Example | Description |
|---|---|---|
BatchPayload | { count: 3 } | A count of the number of records created. |
createMany() is supported by SQLite.skipDuplicates option is not supported by MongoDB, SQLServer, or SQLite.create, createMany, connect, connectOrCreate queries inside a top-level createMany() query. See here for a workaround.createMany query inside an update() or create() query - for example, add a User and two Post records with a nested createMany at the same time.const users = await prisma.user.createMany({
data: [
{ name: "Sonali", email: "[email protected]" },
{ name: "Alex", email: "[email protected]" },
],
});
createManyAndReturn()createManyAndReturn creates multiple records and returns the resulting objects. Supported for PostgreSQL, CockroachDB, and SQLite.
| Name | Type | Required | Description |
|---|---|---|---|
data | Enumerable<UserCreateManyInput> | Yes | Wraps all the model fields in a type so that they can be provided when creating new records. Fields that are marked as optional or have default values in the datamodel are optional. |
select | XOR<UserSelect, null> | No | Specifies which properties to include on the returned objects. |
omit | XOR<UserOmit, null> | No | Specifies which properties to exclude on the returned objects. Excludes specified fields from the result. Mutually exclusive with select. |
include | XOR<UserInclude, null> | No | Specifies which relations should be eagerly loaded on the returned objects. |
skipDuplicates? | boolean | No | Do not insert records with unique fields or ID fields that already exist. Only supported by databases that support ON CONFLICT DO NOTHING. This excludes MongoDB and SQLServer |
skipDuplicates option is not supported by SQLite.createManyAndReturn is not guaranteed.create, createMany, connect, connectOrCreate queries inside a top-level createManyAndReturn() query. See here for a workaround.include, a separate query is generated per relation.relationLoadStrategy: join is not supported.| Return type | Example | Description |
|---|---|---|
| JavaScript array object (typed) | User[] | |
| JavaScript array object (plain) | [{ name: "Sonali" }] | Use select, omit and include to determine which fields to return. |
const users = await prisma.user.createManyAndReturn({
data: [
{ name: "Sonali", email: "[email protected]" },
{ name: "Alex", email: "[email protected]" },
],
});
[
{ "id": 0, "name": "Sonali", "email": "[email protected]", "profileViews": 0 },
{ "id": 1, "name": "Alex", "email": "[email protected]", "profileViews": 0 }
]
updateMany()updateMany updates a batch of existing database records in bulk and returns the number of updated records.
| Name | Type | Required | Description |
|---|---|---|---|
data | XOR<UserUpdateManyMutationInput, | ||
UserUncheckedUpdateManyInput> | Yes | Wraps all the fields of the model so that they can be provided when updating an existing record. Fields that are marked as optional or have default values in the datamodel are optional on data. | |
where | UserWhereInput | No | Wraps all fields of a model so that the list can be filtered by any property. If you do not filter the list, all records will be updated. |
limit | number | No | Limits the number of records to update. |
| Return type | Example | Description |
|---|---|---|
BatchPayload | { count: 4 } | The count of updated records. |
export type BatchPayload = {
count: number;
};
User records where the name is Alice to ALICEconst updatedUserCount = await prisma.user.updateMany({
where: { name: "Alice" },
data: { name: "ALICE" },
});
User records where the email contains prisma.io and at least one related Post has more than 10 likesconst updatedUserCount = await prisma.user.updateMany({
where: {
email: {
contains: "prisma.io",
},
posts: {
some: {
likes: {
gt: 10,
},
},
},
},
data: {
role: "USER",
},
});
User records where the email contains prisma.io, but limit to 5 records updated.const updatedUserCount = await prisma.user.updateMany({
where: {
email: {
contains: "prisma.io",
},
},
data: {
role: "USER",
},
limit: 5,
});
updateManyAndReturn()updateManyAndReturn updates multiple records and returns the resulting objects. Supported for PostgreSQL, CockroachDB, and SQLite.
| Name | Type | Required | Description |
|---|---|---|---|
data | XOR<UserUpdateManyMutationInput, | ||
UserUncheckedUpdateManyInput> | Yes | Wraps all the fields of the model so that they can be provided when updating an existing record. Fields that are marked as optional or have default values in the datamodel are optional on data. | |
where | UserWhereInput | No | Wraps all fields of a model so that the list can be filtered by any property. If you do not filter the list, all records will be updated. |
| Return type | Example | Description |
|---|---|---|
| JavaScript array object (typed) | User[] | |
| JavaScript array object (plain) | [{ name: "Sonali" }] | Use select, omit and include to determine which fields to return. |
const users = await prisma.user.updateManyAndReturn({
where: {
email: {
contains: "prisma.io",
},
},
data: {
role: "ADMIN",
},
});
[
{ "id": 0, "name": "Sonali", "email": "[email protected]", "role": "ADMIN", "profileViews": 0 },
{ "id": 1, "name": "Alex", "email": "[email protected]", "role": "ADMIN", "profileViews": 0 }
]
deleteMany()deleteMany deletes multiple records in a transaction.
| Name | Type | Required | Description |
|---|---|---|---|
where | UserWhereInput | No | Wraps all fields of a model so that the list can be filtered by any field. |
limit | Int | No | Limits the number of records deleted. |
| Return type | Example | Description |
|---|---|---|
BatchPayload | { count: 4 } | The count of deleted records. |
export type BatchPayload = {
count: number;
};
User recordsconst deletedUserCount = await prisma.user.deleteMany({});
User records where the name is Aliceconst deletedUserCount = await prisma.user.deleteMany({
where: { name: "Alice" },
});
User records where the email contains prisma.io, but limit to 5 records deleted.const deletedUserCount = await prisma.user.deleteMany({
where: {
email: {
contains: "prisma.io",
},
},
limit: 5,
});
See Filter conditions and operators for examples of how to filter the records to delete.
count()| Name | Type | Required | Description |
|---|---|---|---|
where | UserWhereInput | No | Wraps all model fields in a type so that the list can be filtered by any property. |
orderBy | XOR<Enumerable<PostOrder | ||
ByInput>, PostOrderByInput> | No | Lets you order the returned list by any property. | |
cursor | UserWhereUniqueInput | No | Specifies the position for the list (the value typically specifies an id or another unique value). |
take | number | No | Specifies how many objects should be returned in the list (as seen from the beginning (positive value) or end (negative value) either of the list or from the cursor position if mentioned) |
skip | number | No | Specifies how many of the returned objects in the list should be skipped. |
| Return type | Example | Description |
|---|---|---|
number | 29 | The count of records. |
UserCountAggregateOutputType | { _all: 27, name: 10 } | Returned if select is used. |
User recordsconst result = await prisma.user.count();
User records with at least one published Postconst result = await prisma.user.count({
where: {
post: {
some: {
published: true,
},
},
},
});
select to perform three separate countsThe following query returns:
_all)null name fieldsnull city fieldsconst c = await prisma.user.count({
select: {
_all: true,
city: true,
name: true,
},
});
aggregate()See also: Aggregation, grouping, and summarizing
| Name | Type | Required | Description |
|---|---|---|---|
where | UserWhereInput | No | Wraps all model fields in a type so that the list can be filtered by any property. |
orderBy | XOR<Enumerable<UserOrderByInput>, | ||
UserOrderByInput> | No | Lets you order the returned list by any property. | |
cursor | UserWhereUniqueInput | No | Specifies the position for the list (the value typically specifies an id or another unique value). |
take | number | No | Specifies how many objects should be returned in the list (as seen from the beginning (positive value) or end (negative value) either of the list or from the cursor position if mentioned) |
skip | number | No | Specifies how many of the returned objects in the list should be skipped. |
_count | true | No | Returns a count of matching records or non-null fields. |
_avg | UserAvgAggregateInputType | No | Returns an average of all values of the specified field. |
_sum | UserSumAggregateInputType | No | Returns the sum of all values of the specified field. |
_min | UserMinAggregateInputType | No | Returns the smallest available value of the specified field. |
_max | UserMaxAggregateInputType | No | Returns the largest available value of the specified field. |
_min, _max, and _count of profileViews of all User recordsconst minMaxAge = await prisma.user.aggregate({
_count: {
_all: true,
},
_max: {
profileViews: true,
},
_min: {
profileViews: true,
},
});
{
_count: { _all: 29 },
_max: { profileViews: 90 },
_min: { profileViews: 0 }
}
_sum of all profileViews for all User recordsconst setValue = await prisma.user.aggregate({
_sum: {
profileViews: true,
},
});
{
"_sum": {
"profileViews": 9493
}
}
groupBy()See also: Aggregation, grouping, and summarizing
| Name | Type | Required | Description |
|---|---|---|---|
where | UserWhereInput | No | Wraps all model fields in a type so that the list can be filtered by any property. |
orderBy | XOR<Enumerable<UserOrderByInput>, | ||
UserOrderByInput> | No | Lets you order the returned list by any property that is also present in by. | |
by | Array<UserScalarFieldEnum> | string | No | Specifies the field or combination of fields to group records by. |
having | UserScalarWhereWithAggregatesInput | No | Allows you to filter groups by an aggregate value - for example, only return groups having an average age less than 50. |
take | number | No | Specifies how many objects should be returned in the list (as seen from the beginning (positive value) or end (negative value) either of the list or from the cursor position if mentioned) |
skip | number | No | Specifies how many of the returned objects in the list should be skipped. |
_count | true | UserCountAggregateInputType | No | Returns a count of matching records or non-null fields. |
_avg | UserAvgAggregateInputType | No | Returns an average of all values of the specified field. |
_sum | UserSumAggregateInputType | No | Returns the sum of all values of the specified field. |
_min | UserMinAggregateInputType | No | Returns the smallest available value of the specified field. |
_max | UserMaxAggregateInputType | No | Returns the largest available value of the specified field. |
country/city where the average profileViews is greater than 200, and return the _sum of profileViews for each groupThe query also returns a count of _all records in each group, and all records with non-null city field values in each group.
const groupUsers = await prisma.user.groupBy({
by: ["country", "city"],
_count: {
_all: true,
city: true,
},
_sum: {
profileViews: true,
},
orderBy: {
country: "desc",
},
having: {
profileViews: {
_avg: {
gt: 200,
},
},
},
});
[
{
country: "Denmark",
city: "Copenhagen",
_sum: { profileViews: 490 },
_count: {
_all: 70,
city: 8,
},
},
{
country: "Sweden",
city: "Stockholm",
_sum: { profileViews: 500 },
_count: {
_all: 50,
city: 3,
},
},
];
findRaw()See: Using Raw SQL (findRaw()).
aggregateRaw()See: Using Raw SQL (aggregateRaw()).
selectselect defines which fields are included in the object that Prisma Client returns. See: Select fields and include relations .
select and include on the same level._count of relations.name and profileViews fields of a single User recordconst result = await prisma.user.findUnique({
where: { id: 1 },
select: {
name: true,
profileViews: true,
},
});
{
name: "Alice",
profileViews: 0
}
email and role fields of a multiple User recordsconst result = await prisma.user.findMany({
select: {
email: true,
role: true,
},
});
[
{
email: "[email protected]",
role: "ADMIN",
},
{
email: "[email protected]",
role: "USER",
},
];
_count of relationsconst usersWithCount = await prisma.user.findMany({
select: {
_count: {
select: { posts: true },
},
},
});
{
_count: {
posts: 3;
}
}
Post recordsconst result = await prisma.user.findMany({
select: {
id: true,
name: true,
posts: {
select: {
id: true,
title: true,
},
},
},
});
[
{
id: 1,
name: "Alice",
posts: [
{ id: 1, title: "Hello World" },
{ id: 2, title: "Bye bye" },
],
},
{
id: 2,
name: "Bob",
posts: [],
},
];
include inside selectconst result = await prisma.user.findMany({
select: {
id: true,
name: true,
posts: {
include: {
author: true,
},
},
},
});
[
{
id: 1,
name: "Alice",
posts: [
{
id: 1,
title: "Hello World",
published: true,
author: {
id: 1,
name: "Alice",
email: "[email protected]",
role: "ADMIN",
coinflips: [true, false],
profileViews: 0,
},
},
{
id: 2,
title: "Bye bye",
published: false,
author: {
id: 1,
name: "Alice",
email: "[email protected]",
role: "USER",
coinflips: [],
profileViews: 0,
},
},
],
},
];
includeinclude defines which relations are included in the result that Prisma Client returns. See: Select fields and include relations .
include a _count of relations.posts and profile relation when loading User recordsconst users = await prisma.user.findMany({
include: {
posts: true, // Returns all fields for all posts
profile: true, // Returns all Profile fields
},
});
posts relation on the returned objects when creating a new User record with two Post recordsconst user = await prisma.user.create({
data: {
email: "[email protected]",
posts: {
create: [{ title: "This is my first post" }, { title: "Here comes a second post" }],
},
},
include: { posts: true }, // Returns all fields for all posts
});
includeThe following example demonstrates how to use TypeScript's satisfies operator with include:
const includePosts = { posts: true } satisfies Prisma.UserInclude;
_count of relationsconst usersWithCount = await prisma.user.findMany({
include: {
_count: {
select: { posts: true },
},
},
});
{ id: 1, name: "Bob", email: "[email protected]", _count: { posts: 3 } },
{ id: 2, name: "Enya", email: "[email protected]", _count: { posts: 2 } }
omitomit defines which fields are excluded in the object that Prisma Client returns.
omit and select since they serve opposite purposes.password field from all User recordsconst result = await prisma.user.findMany({
omit: {
password: true,
},
});
[
{
id: 1,
email: "[email protected]",
name: "Jenny",
},
{
id: 2,
email: "[email protected]",
name: "Rose",
},
];
title fields from all User's posts relationconst results = await prisma.user.findMany({
omit: {
password: true,
},
include: {
posts: {
omit: {
title: true,
},
},
},
});
[
{
id: 1,
email: "[email protected]",
name: "Jenny",
posts: [
{
id: 1,
author: {
id: 1,
email: "[email protected]",
name: "Jenny",
},
authorId: 1,
},
],
},
{
id: 2,
email: "[email protected]",
name: "Rose",
posts: [
{
id: 2,
author: {
id: 2,
email: "[email protected]",
name: "Rose",
},
authorId: 2,
},
],
},
];
omitThe following example demonstrates how to use TypeScript's satisfies operator with omit:
const omitPassword = { password: true } satisfies Prisma.UserOmit;
relationLoadStrategy (Preview)relationLoadStrategy specifies how a relation should be loaded from the database. It has two possible values:
join (default): Uses a database-level LATERAL JOIN (PostgreSQL) or correlated subqueries (MySQL) and fetches all data with a single query to the database.query: Sends multiple queries to the database (one per table) and joins them on the application level.Note: Once
relationLoadStrategymoves from Preview into General Availability,joinwill universally become the default for all relation queries.
You can learn more about join strategies here.
Because the relationLoadStrategy option is currently in Preview, you need to enable it via the relationJoins preview feature flag in your Prisma schema file:
generator client {
provider = "prisma-client"
output = "./generated"
previewFeatures = ["relationJoins"]
}
After adding this flag, you need to run prisma generate again to re-generate Prisma Client. The relationJoins feature is currently available on PostgreSQL, CockroachDB and MySQL.
join strategy will be more effective. Use query if you want to save resources on your database server or if you profiling shows that the application-level join is more performant.relationLoadStrategy on the top-level in your query. The top-level choice will affect all nested sub-queries.posts relation via a database-level JOIN when using includeconst users = await prisma.user.findMany({
relationLoadStrategy: "join",
include: {
posts: true,
},
});
posts relation via a database-level JOIN when using selectconst users = await prisma.user.findMany({
relationLoadStrategy: "join",
select: {
posts: true,
},
});
wherewhere defines one or more filters, and can be used to filter on record properties (like a user's email address) or related record properties (like a user's top 10 most recent post titles).
const results = await prisma.user.findMany({
where: {
email: {
endsWith: "prisma.io",
},
},
});
whereThe following examples demonstrate how to use TypeScript's satisfies operator with where:
UserWhereInput
// UserWhereInput
const whereNameIs = { name: "Rich" } satisfies Prisma.UserWhereInput;
// It can be combined with conditional operators too
const whereNameIsWithAnd = {
name: "Rich",
AND: [
{
email: {
contains: "[email protected]",
},
},
],
} satisfies Prisma.UserWhereInput;
UserWhereUniqueInput This type works by exposing any unique fields on the model. A field assigned @id is considered unique,
as is one assigned @unique.
This type exposes all fields on the model. This means that when you filter for a single record based on a unique field, you can check additional non-unique and unique fields at the same time. Learn more.
// UserWhereUniqueInput
const whereEmailIsUnique = { email: "[email protected]" } satisfies Prisma.UserWhereUniqueInput;
PostScalarWhereInput
const whereScalarTitleIs = { title: "boop" } satisfies Prisma.PostScalarWhereInput;
PostUpdateWithWhereUniqueWithoutAuthorInput - This type accepts a unique where field (an @id or another assigned @unique)
and updates any field on the Post model except the Author. The Author is the scalar field on the Post model.
const updatePostByIdWithoutAuthor = {
where: { id: 1 },
data: {
content: "This is some updated content",
published: true,
title: "This is a new title",
},
} satisfies Prisma.PostUpdateWithWhereUniqueWithoutAuthorInput;
PostUpsertWithWhereUniqueWithoutAuthorInput - This type will update the Post records title field where the id matches, if it doesn't exist it will create it instead.
const updatePostTitleOrCreateIfNotExist = {
where: { id: 1 },
update: { title: "This is a new title" },
create: {
id: 1,
title: "If the title doesn't exist, then create one with this text",
},
} satisfies Prisma.PostUpsertWithWhereUniqueWithoutAuthorInput;
PostUpdateManyWithWhereWithoutAuthorInput - This type will update all Post records where published is set to false.
const publishAllPosts = {
where: { published: { equals: false } },
data: { published: true },
} satisfies Prisma.PostUpdateManyWithWhereWithoutAuthorInput;
orderBySorts a list of records. See also: Sorting
null records first or last. For details, see Sort with nulls first or last.sort argument| Name | Description |
|---|---|
asc | Sort ascending (A → Z) |
desc | Sort descending (Z → A) |
nulls argumentNote:
| Name | Description |
|---|---|
first | Sort with null values first. |
last | Sort with null values last. |
User by email fieldThe following example returns all User records sorted by email ascending:
const users = await prisma.user.findMany({
orderBy: {
email: "asc",
},
});
The following example returns all User records sorted by email descending:
const users = await prisma.user.findMany({
orderBy: {
email: "desc",
},
});
Post by the related User record's nameThe following query orders posts by user name:
const posts = await prisma.post.findMany({
orderBy: {
author: {
name: "asc",
},
},
});
Post by the related User record's name, with null records firstThe following query orders posts by user name, with null records first:
const posts = await prisma.post.findMany({
orderBy: {
author: {
name: { sort: "asc", nulls: "first" },
},
},
});
Post by relevance of the title:::info
For PostgreSQL, this feature is still in Preview. Enable the fullTextSearchPostgres feature flag in order to use it.
:::
The following query orders posts by relevance of the search term 'database' to the title:
const posts = await prisma.post.findMany({
orderBy: {
_relevance: {
fields: ['title'],
search: 'database',
sort: 'asc'
},
})
User by the posts countThe following query orders users by post count:
const getActiveusers = await prisma.user.findMany({
orderBy: {
posts: {
count: "desc",
},
},
});
User by multiple fields - email and roleThe following example sorts users by two fields - first email, then role:
const users = await prisma.user.findMany({
select: {
email: true,
role: true,
},
orderBy: [
{
email: "desc",
},
{
role: "desc",
},
],
});
[
{
"email": "[email protected]",
"role": "USER"
},
{
"email": "[email protected]",
"role": "USER"
},
{
"email": "[email protected]",
"role": "MODERATOR"
},
{
"email": "[email protected]",
"role": "MODERATOR"
},
{
"email": "[email protected]",
"role": "USER"
},
{
"email": "[email protected]",
"role": "ADMIN"
},
{
"email": "[email protected]",
"role": "USER"
},
{
"email": "[email protected]",
"role": "USER"
}
]
The order of sorting parameters matters - the following query sorts by role, then email. Note the difference in the results:
const users = await prisma.user.findMany({
select: {
email: true,
role: true,
},
orderBy: [
{
role: "desc",
},
{
email: "desc",
},
],
});
[
{
"email": "[email protected]",
"role": "MODERATOR"
},
{
"email": "[email protected]",
"role": "MODERATOR"
},
{
"email": "[email protected]",
"role": "USER"
},
{
"email": "[email protected]",
"role": "USER"
},
{
"email": "[email protected]",
"role": "USER"
},
{
"email": "[email protected]",
"role": "USER"
},
{
"email": "[email protected]",
"role": "USER"
},
{
"email": "[email protected]",
"role": "ADMIN"
}
]
User by email, select name and emailThe following example returns all the name and email fields of all User records, sorted by email:
const users3 = await prisma.user.findMany({
orderBy: {
email: "asc",
},
select: {
name: true,
email: true,
},
});
[
{
name: "Alice",
email: "[email protected]",
},
{
name: "Ariadne",
email: "[email protected]",
},
{
name: "Bob",
email: "[email protected]",
},
];
User records by email and sort nested Post records by titleThe following example:
User records sorted by emailUser record, returns the title field of all nested Post records sorted by titleconst usersWithPosts = await prisma.user.findMany({
orderBy: {
email: "asc",
},
include: {
posts: {
select: {
title: true,
},
orderBy: {
title: "asc",
},
},
},
});
[
{
"id": 2,
"email": "[email protected]",
"name": "Alice",
"posts": [
{
"title": "Watch the talks from Prisma Day 2019"
}
]
},
{
"id": 3,
"email": "[email protected]",
"name": "Ariadne",
"posts": [
{
"title": "How to connect to a SQLite database"
},
{
"title": "My first day at Prisma"
}
]
},
{
"id": 1,
"email": "[email protected]",
"name": "Bob",
"posts": [
{
"title": "Follow Prisma on Twitter"
},
{
"title": "Subscribe to GraphQL Weekly for community news "
}
]
}
]
Post recordsThe following example retrieves a single User record by ID, as well as a list of nested Post records sorted by title:
const userWithPosts = await prisma.user.findUnique({
where: {
id: 1,
},
include: {
posts: {
orderBy: {
title: "desc",
},
select: {
title: true,
published: true,
},
},
},
});
{
"email": "[email protected]",
"id": 1,
"name": "Sarah",
"extendedProfile": null,
"role": "USER",
"posts": [
{
"title": "Prisma Day 2020",
"published": false
},
{
"title": "My first post",
"published": false
},
{
"title": "All about databases",
"published": true
}
]
}
enumThe following sorts all User records by role (an enum):
const sort = await prisma.user.findMany({
orderBy: {
role: "desc",
},
select: {
email: true,
role: true,
},
});
[
{
"email": "[email protected]",
"role": "USER"
},
{
"email": "[email protected]",
"role": "ADMIN"
},
{
"email": "[email protected]",
"role": "ADMIN"
},
{
"email": "[email protected]",
"role": "ADMIN"
}
]
orderByThe following examples demonstrate how to use TypeScript's satisfies operator with orderBy:
UserOrderByInput
const orderEmailsByDescending = { email: "desc" } satisfies Prisma.UserOrderByInput;
distinctDeduplicate a list of records from findMany or findFirst. See also: Aggregation, grouping, and summarizing
The following example returns all distinct city fields, and selects only the city and country fields:
const distinctCities = await prisma.user.findMany({
select: {
city: true,
country: true,
},
distinct: ["city"],
});
[
{ city: "Paris", country: "France" },
{ city: "Lyon", country: "France" },
];
The following example returns all distinct city and country field combinations, and selects only the city and country fields:
const distinctCitiesAndCountries = await prisma.user.findMany({
select: {
city: true,
country: true,
},
distinct: ["city", "country"],
});
[
{ city: "Paris", country: "France" },
{ city: "Paris", country: "Denmark" },
{ city: "Lyon", country: "France" },
];
Note that there is now a "Paris, Denmark" in addition to "Paris, France":
The following example returns all distinct city and country field combinations where the user's email contains "prisma.io", and selects only the city and country fields:
const distinctCitiesAndCountries = await prisma.user.findMany({
where: {
email: {
contains: "prisma.io",
},
},
select: {
city: true,
country: true,
},
distinct: ["city", "country"],
});
[
{ city: "Paris", country: "Denmark" },
{ city: "Lyon", country: "France" },
];
nativeDistinctEnabling nativeDistinct in your Prisma schema pushes the distinct operation to the database layer
(where supported). This can significantly improve performance. However, note that:
To enable nativeDistinct:
generator client {
provider = "prisma-client"
output = "./generated"
previewFeatures = ["nativeDistinct"]
}
See Preview Features for more details.
createA nested create query adds a new related record or set of records to a parent record. See: Working with relations
create is available as a nested query when you create() (prisma.user.create(...)) a new parent record or update() (prisma.user.update(...)) an existing parent record.create or a nested createMany to create multiple related records. If you require the skipDuplicates query option you should use createMany.User record with a new Profile recordconst user = await prisma.user.create({
data: {
email: '[email protected]',
profile: {
create: { bio: 'Hello World' },
},
},
});
Profile record with a new User recordconst user = await prisma.profile.create({
data: {
bio: "Hello World",
user: {
create: { email: "[email protected]" }, // [!code highlight]
},
},
});
User record with a new Post recordconst user = await prisma.user.create({
data: {
email: "[email protected]",
posts: {
create: { title: "Hello World" },
},
},
});
User record with two new Post recordsBecause it's a one-to-many relation, you can also create multiple Post records at once by passing an array to create:
const user = await prisma.user.create({
data: {
email: "[email protected]",
posts: {
create: [
{
title: "This is my first post",
},
{
title: "Here comes a second post",
},
],
},
},
});
Note: You can also use a nested createMany to achieve the same result.
User record by creating a new Profile recordconst user = await prisma.user.update({
where: { email: "[email protected]" },
data: {
profile: {
create: { bio: "Hello World" },
},
},
});
User record by creating a new Post recordconst user = await prisma.user.update({
where: { email: "[email protected]" },
data: {
posts: {
create: { title: "Hello World" }, // [!code highlight]
},
},
});
createManyA nested createMany query adds a new set of records to a parent record. See: Working with relations
createMany is available as a nested query when you create() (prisma.user.create(...)) a new parent record or update() (prisma.user.update(...)) an existing parent record.
prisma.user.create(...) a user and use a nested createMany to create multiple posts (posts have one user).prisma.post.create(...) a post and use a nested createMany to create categories (many posts have many categories).create or createMany.categoryId on a post.createMany is supported by SQLite.create or a nested createMany to create multiple related records - if you do not need the skipDuplicates query option, you should probably use create.| Name | Type | Required | Description |
|---|---|---|---|
data | Enumerable<UserCreateManyInput> | Yes | Wraps all the model fields in a type so that they can be provided when creating new records. Fields that are marked as optional or have default values in the datamodel are optional. |
skipDuplicates? | boolean | No | Do not insert records with unique fields or ID fields that already exist. Only supported by databases that support ON CONFLICT DO NOTHING. This excludes MongoDB and SQLServer |
User and multiple new related Post recordsconst user = await prisma.user.update({
where: {
id: 9,
},
data: {
name: "Elliott",
posts: {
createMany: {
data: [{ title: "My first post" }, { title: "My second post" }],
},
},
},
});
setset overwrites the value of a relation - for example, replacing a list of Post records with a different list. See: Working with relations
User record by disconnecting any previous Post records and connecting two other existing onesconst user = await prisma.user.update({
where: { email: "[email protected]" },
data: {
posts: {
set: [{ id: 32 }, { id: 42 }],
},
},
});
connectA nested connect query connects a record to an existing related record by specifying an ID or unique identifier. See: Working with relations
connect is available as a nested query when you create a new parent record or update an existing parent record.
If the related record does not exist, Prisma Client throws an exception:
The required connected records were not found. Expected 1 records to be connected, found 0.
When using set and connect together, the order in which they are applied significantly impacts the result. If set is used before connect, the connected records will only reflect the final state established by the connect operation, as set clears all existing connections before connect establishes new ones. Conversely, if connect is applied before set, the set operation will override the connect action by clearing all connected records and replacing them with its own specified state.
Profile record and connect it to an existing User record via unique fieldconst user = await prisma.profile.create({
data: {
bio: "Hello World",
user: {
connect: { email: "[email protected]" },
},
},
});
Profile record and connect it to an existing User record via an ID fieldconst user = await prisma.profile.create({
data: {
bio: "Hello World",
user: {
connect: { id: 42 }, // sets userId of Profile record
},
},
});
You can also set the foreign key directly:
const user = await prisma.profile.create({
data: {
bio: "Hello World",
userId: 42,
},
});
However, you can't use both the direct approach and the connect approach in the same query. See this issue comment for details.
Post record and connect it to an existing User recordconst user = await prisma.post.create({
data: {
title: "Hello World",
author: {
connect: { email: "[email protected]" },
},
},
});
User record by connecting it to an existing Profile recordconst user = await prisma.user.update({
where: { email: "[email protected]" },
data: {
profile: {
connect: { id: 24 },
},
},
});
User record by connecting it to two existing Post recordsconst user = await prisma.user.update({
where: { email: "[email protected]" },
data: {
posts: {
connect: [{ id: 24 }, { id: 42 }],
},
},
});
connectOrCreateconnectOrCreate either connects a record to an existing related record by ID or unique identifier or creates a new related record if the record does not exist. See: Working with relations
Multiple connectOrCreate queries that run as concurrent transactions can result in a race condition. Consider the following example, where two queries attempt to connectOrCreate a blog post tag named computing at the same time (tag names must be unique):
const createPost = await prisma.post.create({
data: {
title: "How to create a compiler",
content: "...",
author: {
connect: {
id: 9,
},
},
tags: {
connectOrCreate: {
create: {
name: "computing",
},
where: {
name: "computing",
},
},
},
},
});
const createPost = await prisma.post.create({
data: {
title: "How to handle schema drift in production",
content: "...",
author: {
connect: {
id: 15,
},
},
tags: {
connectOrCreate: {
create: {
name: "computing",
},
where: {
name: "computing",
},
},
},
},
});
If query A and query B overlap in the following way, query A results in an exception:
| Query A (Fail ❌) | Query B (Success ✅) |
|---|---|
| Query hits server, starts transaction A | Query hits server, starts transaction B |
Find record where tagName equals computing, record not found | |
Find record where tagName equals computing, record not found | |
Create record where tagName equals computing and connect | |
Create record where tagName equals computing | |
| Unique violation, record already created by transaction B |
To work around this scenario, we recommend catching the unique violation exception (PrismaClientKnownRequestError, error P2002) and retrying failed queries.
Profile record, then connect it to an existing User record or create a new UserThe following example:
ProfileUser where the email address is [email protected]const user = await prisma.profile.create({
data: {
bio: 'The coolest Alice on the planet',
user: {
connectOrCreate: {
where: { email: '[email protected]' },
create: { email: '[email protected]'}
},
},
})
Post record and connect it to an existing User record, or create a new Userconst user = await prisma.post.create({
data: {
title: "Hello World",
author: {
connectOrCreate: {
where: { email: "[email protected]" },
create: { email: "[email protected]" },
},
},
},
});
User record by connecting it to an existing Profile record, or creating a new Profile recordThe following example:
Profile with an id of 20const updateUser = await prisma.user.update({
where: { email: "[email protected]" },
data: {
profile: {
connectOrCreate: {
where: { id: 20 },
create: {
bio: "The coolest Alice in town",
},
},
},
},
});
User record by connect it to two existing Post records, or creating two new Post recordsconst user = await prisma.user.update({
where: { email: "[email protected]" },
data: {
posts: {
connectOrCreate: [
{
where: { id: 32 },
create: { title: "This is my first post" },
},
{
where: { id: 19 },
create: { title: "This is my second post" },
},
],
},
},
});
disconnectA nested disconnect query breaks the connection between a parent record and a related record, but does not delete either record. See: Working with relations
disconnect is only available if the relation is optional.User record by disconnecting the Profile record it's connected toconst user = await prisma.user.update({
where: { email: "[email protected]" },
data: {
profile: {
disconnect: true,
},
},
});
User record by disconnecting two Post records it's connected toconst user = await prisma.user.update({
where: { email: "[email protected]" },
data: {
posts: {
disconnect: [{ id: 44 }, { id: 46 }],
},
},
});
updateA nested update query updates one or more related records where the parent record's ID is n. See: Working with relations
Nested update queries are only available in the context of a top-level update query (for example, prisma.user.update(...)).
If the parent record does not exist, Prisma Client throws an exception:
AssertionError("Expected a valid parent ID to be present for nested update to-one case.")
If the related record that you want to update does not exist, Prisma Client throws an exception:
AssertionError("Expected a valid parent ID to be present for nested update to-one case.")
User record by updating the Profile record it's connected toconst user = await prisma.user.update({
where: { email: "[email protected]" },
data: {
profile: {
update: { bio: "Hello World" },
},
},
});
User record by updating two Post records it's connected toconst user = await prisma.user.update({
where: { email: "[email protected]" },
data: {
posts: {
update: [
{
data: { published: true },
where: { id: 32 },
},
{
data: { published: true },
where: { id: 23 },
},
],
},
},
});
upsert:::info
This section covers the usage of nested upsert within update(). To learn about the upsert() operation, reference the linked documentation.
:::
A nested upsert query updates a related record if it exists, or creates a new related record.
User record by updating the Profile record it's connected to or creating a new one (upsert)const user = await prisma.user.update({
where: { email: "[email protected]" },
data: {
profile: {
upsert: {
create: { bio: "Hello World" },
update: { bio: "Hello World" },
},
},
},
});
User record by updating two Post record it's connected to or creating new ones (upsert)const user = await prisma.user.update({
where: { email: "[email protected]" },
data: {
posts: {
upsert: [
{
create: { title: "This is my first post" },
update: { title: "This is my first post" },
where: { id: 32 },
},
{
create: { title: "This is my second post" },
update: { title: "This is my second post" },
where: { id: 23 },
},
],
},
},
});
deleteA nested delete query deletes a related record. The parent record is not deleted.
delete is only available if the relation is optional.User record by deleting the Profile record it's connected toconst user = await prisma.user.update({
where: { email: "[email protected]" },
data: {
profile: {
delete: true,
},
},
});
User record by deleting two Post records it's connected toconst user = await prisma.user.update({
where: { email: "[email protected]" },
data: {
posts: {
delete: [{ id: 34 }, { id: 36 }],
},
},
});
updateManyA nested updateMany updates a list of related records and supports filtering - for example, you can update a user's unpublished posts.
const result = await prisma.user.update({
where: {
id: 2,
},
data: {
posts: {
updateMany: {
where: {
published: false,
},
data: {
likes: 0,
},
},
},
},
});
deleteManyA nested deleteMany deletes related records and supports filtering. For example, you can delete a user's posts while updating other properties of that user.
const result = await prisma.user.update({
where: {
id: 2,
},
data: {
name: "Updated name",
posts: {
deleteMany: {},
},
},
});
equalsValue equals n.
Return all users where name equals "Eleanor"
const result = await prisma.user.findMany({
where: {
name: {
equals: "Eleanor",
},
},
});
You can also exclude the equals:
const result = await prisma.user.findMany({
where: {
name: "Eleanor",
},
});
Return all products with a quantity lower than the "warn quantity" threshold
This example compares fields of the same model.
const productsWithLowQuantity = await prisma.product.findMany({
where: {
quantity: {
lte: prisma.product.fields.warnQuantity,
},
},
});
Return all users that have blue and green as their favorite colors
This example finds users that have set their favoriteColors field to ['blue', 'green'].
Note that when using equals, order of elements matters. That is to say ['blue', 'green'] is not equal to ['green', 'blue']
const favoriteColorFriends = await prisma.user.findMany({
where: {
favoriteColors: {
equals: ["blue", "green"],
},
},
});
notValue does not equal n.
name does not equal "Eleanor"const result = await prisma.user.findMany({
where: {
name: {
not: "Eleanor",
},
},
});
:::warning
not will return all items that do not match a given value. However, if the column is nullable, NULL values will not be returned. If you require null values to be returned, use an OR operator to include NULL values.
:::
name does not equal "Eleanor" including users where name is NULLawait prisma.user.findMany({
where: {
OR: [{ name: { not: "Eleanor" } }, { name: null }],
},
});
inValue n exists in list.
:::note
null values are not returned. For example, if you combine in and NOT to return a user whose name is not in the list, users with null value names are not returned.
:::
User records where the id can be found in the following list: [22, 91, 14, 2, 5]const getUser = await prisma.user.findMany({
where: {
id: { in: [22, 91, 14, 2, 5] },
},
});
User records where the name can be found in the following list: ['Saqui', 'Clementine', 'Bob']const getUser = await prisma.user.findMany({
where: {
name: { in: ["Saqui", "Clementine", "Bob"] },
},
});
User records where name is not present in the listThe following example combines in and NOT. You can also use notIn.
const getUser = await prisma.user.findMany({
where: {
NOT: {
name: { in: ["Saqui", "Clementine", "Bob"] },
},
},
});
User record where at least one Post has at least one specified Categoryconst getUser = await prisma.user.findMany({
where: {
// Find users where..
posts: {
some: {
// ..at least one (some) posts..
categories: {
some: {
// .. have at least one category ..
name: {
in: ["Food", "Introductions"], // .. with a name that matches one of the following.
},
},
},
},
},
},
});
notInValue n does not exist in list.
null values are not returned.User records where the id can not be found in the following list: [22, 91, 14, 2, 5]const getUser = await prisma.user.findMany({
where: {
id: { notIn: [22, 91, 14, 2, 5] },
},
});
ltValue n is less than x.
Post records where likes is less than 9const getPosts = await prisma.post.findMany({
where: {
likes: {
lt: 9,
},
},
});
lteValue n is less than or equal to x.
Post records where likes is less or equal to 9const getPosts = await prisma.post.findMany({
where: {
likes: {
lte: 9,
},
},
});
gtValue n is greater than x.
Post records where likes is greater than 9const getPosts = await prisma.post.findMany({
where: {
likes: {
gt: 9,
},
},
});
gteValue n is greater than or equal to x.
Post records where likes is greater than or equal to 9const getPosts = await prisma.post.findMany({
where: {
likes: {
gte: 9,
},
},
});
Post records where date_created is greater than March 19th, 2020const result = await prisma.post.findMany({
where: {
date_created: {
gte: new Date("2020-03-19T14:21:00+0200") /* Includes time offset for UTC */,
},
},
});
containsValue n contains x.
Post records where content contains databasesconst result = await prisma.post.count({
where: {
content: {
contains: "databases",
},
},
});
Post records where content does not contain databasesconst result = await prisma.post.count({
where: {
NOT: {
content: {
contains: "databases",
},
},
},
});
searchUse Full-Text Search to search within a String field.
:::info
For PostgreSQL, this feature is still in Preview. Enable the fullTextSearchPostgres feature flag in order to use it.
:::
cat or dog.const result = await prisma.post.findMany({
where: {
title: {
search: "cat | dog",
},
},
});
cat and dog.const result = await prisma.post.findMany({
where: {
title: {
search: "cat & dog",
},
},
});
cat.const result = await prisma.post.findMany({
where: {
title: {
search: "!cat",
},
},
});
modePost records where title contains prisma, in a case insensitive wayconst result = await prisma.post.findMany({
where: {
title: {
contains: "prisma",
mode: "insensitive",
},
},
});
startsWithPost records where title starts with Pr (such as Prisma)const result = await prisma.post.findMany({
where: {
title: {
startsWith: "Pr",
},
},
});
endsWithUser records where email ends with prisma.ioconst result = await prisma.user.findMany({
where: {
email: {
endsWith: "prisma.io",
},
},
});
ANDAll conditions must return true. Alternatively, pass a list of objects into the where clause - the AND operator is not required.
Post records where the content field contains Prisma and published is falseconst result = await prisma.post.findMany({
where: {
AND: [
{
content: {
contains: "Prisma",
},
},
{
published: {
equals: false,
},
},
],
},
});
Post records where the content field contains Prisma and published is false (no AND)The following format returns the same results as the previous example without the AND operator:
const result = await prisma.post.findMany({
where: {
content: {
contains: "Prisma",
},
published: {
equals: false,
},
},
});
Post records where the title field contains Prisma or databases, and published is falseThe following example combines OR and AND:
const result = await prisma.post.findMany({
where: {
OR: [
{
title: {
contains: "Prisma",
},
},
{
title: {
contains: "databases",
},
},
],
AND: {
published: false,
},
},
});
OROne or more conditions must return true.
Post records where the title field contains Prisma or databasesconst result = await prisma.post.findMany({
where: {
OR: [
{
title: {
contains: "Prisma",
},
},
{
title: {
contains: "databases",
},
},
],
},
});
Post records where the title field contains Prisma or databases, but not SQLThe following example combines OR and NOT:
const result = await prisma.post.findMany({
where: {
OR: [
{
title: {
contains: "Prisma",
},
},
{
title: {
contains: "databases",
},
},
],
NOT: {
title: {
contains: "SQL",
},
},
},
});
Post records where the title field contains Prisma or databases, and published is falseThe following example combines OR and AND:
const result = await prisma.post.findMany({
where: {
OR: [
{
title: {
contains: "Prisma",
},
},
{
title: {
contains: "databases",
},
},
],
AND: {
published: false,
},
},
});
NOTAll conditions must return false.
Post records where the title does not contain SQLconst result = await prisma.post.findMany({
where: {
NOT: {
title: {
contains: "SQL",
},
},
},
});
Post records where the title field contains Prisma or databases, but not SQL, and the related User record' email address does not contain sarahconst result = await prisma.post.findMany({
where: {
OR: [
{
title: {
contains: "Prisma",
},
},
{
title: {
contains: "databases",
},
},
],
NOT: {
title: {
contains: "SQL",
},
},
user: {
NOT: {
email: {
contains: "sarah",
},
},
},
},
include: {
user: true,
},
});
someReturns all records where one or more ("some") related records match filtering criteria.
some without parameters to return all records with at least one relationUser records where some posts mention Prismaconst result = await prisma.user.findMany({
where: {
post: {
some: {
content: {
contains: "Prisma"
}
}
}
}
}
everyReturns all records where all ("every") related records match filtering criteria.
User records where all posts are publishedconst result = await prisma.user.findMany({
where: {
post: {
every: {
published: true
},
}
}
}
noneReturns all records where zero related records match filtering criteria.
none without parameters to return all records with no relationsUser records with zero postsconst result = await prisma.user.findMany({
where: {
post: {
none: {} // User has no posts
}
}
}
User records with zero published postsconst result = await prisma.user.findMany({
where: {
post: {
none: {
published: true
}
}
}
}
isReturns all records where related record matches filtering criteria (for example, user's name is Bob).
Post records where user's name is "Bob"const result = await prisma.post.findMany({
where: {
user: {
is: {
name: "Bob"
},
}
}
}
isNotReturns all records where the related record does not match the filtering criteria (for example, user's name isNot Bob).
Post records where user's name is NOT "Bob"const result = await prisma.post.findMany({
where: {
user: {
isNot: {
name: "Bob"
},
}
}
}
setUse set to overwrite the value of a scalar list field.
set is optional - you can set the value directly:
tags: ["computers", "books"];
tags to a list of string valuesconst setTags = await prisma.post.update({
where: {
id: 9,
},
data: {
tags: {
set: ["computing", "books"],
},
},
});
tags to a list of values without using the set keywordconst setTags = await prisma.post.update({
where: {
id: 9,
},
data: {
tags: ["computing", "books"],
},
});
tags to a single string valueconst setTags = await prisma.post.update({
where: {
id: 9,
},
data: {
tags: {
set: "computing",
},
},
});
pushUse push to add one value or multiple values to a scalar list field.
computing item to the tags listconst addTag = await prisma.post.update({
where: {
id: 9,
},
data: {
tags: {
push: "computing",
},
},
});
const addTag = await prisma.post.update({
where: {
id: 9,
},
data: {
tags: {
push: ["computing", "genetics"],
},
},
});
unsetUse unset to unset the value of a scalar list (MongoDB only). Unlike set: null, unset removes the list entirely.
tagsconst setTags = await prisma.post.update({
where: {
id: 9,
},
data: {
tags: {
unset: true,
},
},
});
Scalar list filters allow you to filter by the contents of a list / array field.
:::warning
Available for PostgreSQL, CockroachDB, and MongoDB.
:::
NULL values . Using isEmpty or NOT does not return records with NULL value lists / arrays, and { equals: null } results in an error.hasThe given value exists in the list.
The following query returns all Post records where the tags list includes "databases":
const posts = await client.post.findMany({
where: {
tags: {
has: "databases",
},
},
});
The following query returns all Post records where the tags list does not include "databases":
const posts = await client.post.findMany({
where: {
NOT: {
tags: {
has: "databases",
},
},
},
});
hasEveryEvery value exists in the list.
The following query returns all Post records where the tags list includes at least "databases" and "typescript":
const posts = await prisma.post.findMany({
where: {
tags: {
hasEvery: ["databases", "typescript"],
},
},
});
hasSomeAt least one value exists in the list.
The following query returns all Post records where the tags list includes "databases" or "typescript":
const posts = await prisma.post.findMany({
where: {
tags: {
hasSome: ["databases", "typescript"],
},
},
});
isEmptyThe list is empty.
The following query returns all Post records that have no tags:
const posts = await prisma.post.findMany({
where: {
tags: {
isEmpty: true,
},
},
});
isSetFilter lists to include only results that have been set (MongoDB only) (either set to a value, or explicitly set to null). Setting this filter to true will exclude undefined results that are not set at all.
The following query returns all Post records where the tags have been set to either null or a value:
const posts = await prisma.post.findMany({
where: {
tags: {
isSet: true,
},
},
});
equalsThe list matches the given value exactly.
The following query returns all Post records where the tags list includes "databases" and "typescript" only:
const posts = await prisma.post.findMany({
where: {
tags: {
equals: ["databases", "typescript"],
},
},
});
Composite type methods allow you to create, update and delete composite types (MongoDB only).
setUse set to overwrite the value of a composite type.
set keyword is optional - you can set the value directly:
photos: [
{ height: 100, width: 200, url: "1.jpg" },
{ height: 100, width: 200, url: "2.jpg" },
];
shippingAddress composite type within a new orderconst order = await prisma.order.create({
data: {
// Normal relation
product: { connect: { id: "some-object-id" } },
color: "Red",
size: "Large",
// Composite type
shippingAddress: {
set: {
street: "1084 Candycane Lane",
city: "Silverlake",
zip: "84323",
},
},
},
});
nullconst order = await prisma.order.create({
data: {
// Embedded optional type, set to null
billingAddress: {
set: null,
},
},
});
unsetUse unset to unset the value of a composite type. Unlike set: null, this removes the field entirely from the MongoDB document.
billingAddress from an orderconst order = await prisma.order.update({
where: {
id: "some-object-id",
},
data: {
billingAddress: {
// Unset the billing address
// Removes "billingAddress" field from order
unset: true,
},
},
});
updateUse update to update fields within a required composite type.
The update method cannot be used on optional types. Instead, use upsert
shippingAddress composite typeconst order = await prisma.order.update({
where: {
id: "some-object-id",
},
data: {
shippingAddress: {
// Update just the zip field
update: {
zip: "41232",
},
},
},
});
upsertUse upsert to update an existing optional composite type if it exists, and otherwise set the composite type.
The upsert method cannot be used on required types. Instead, use update
billingAddress if it doesn't exist, and otherwise update itconst order = await prisma.order.update({
where: {
id: "some-object-id",
},
data: {
billingAddress: {
// Create the address if it doesn't exist,
// otherwise update it
upsert: {
set: {
street: "1084 Candycane Lane",
city: "Silverlake",
zip: "84323",
},
update: {
zip: "84323",
},
},
},
},
});
pushUse push to push values to the end of a list of composite types.
photos listconst product = prisma.product.update({
where: {
id: 10,
},
data: {
photos: {
// Push a photo to the end of the photos list
push: [{ height: 100, width: 200, url: "1.jpg" }],
},
},
});
Composite type filters allow you to filter the contents of composite types (MongoDB only).
equalsUse equals to filter results by matching a composite type or a list of composite types. Requires all required fields of the composite type to match.
When matching optional fields, you need to distinguish between undefined (missing) fields of the document, and fields that have been explicitly set to null:
nullnull values of an optional field with equals: { ... exampleField: null ... }, then it will match only documents where the field has been set to null, and not undefined fieldsThe ordering of fields and lists matters when using equals:
{ "a": "1", "b": "2" } and { "b": "2", "a": "1" } are not considered equal[ { "a": 1 }, { "a": 2 } ] and [ { "a": 2 }, { "a": 1 } ] are not considered equalshippingAddressconst orders = await prisma.order.findMany({
where: {
shippingAddress: {
equals: {
street: "555 Candy Cane Lane",
city: "Wonderland",
zip: "52337",
},
},
},
});
urlsconst product = prisma.product.findMany({
where: {
equals: {
photos: [{ url: "1.jpg" }, { url: "2.jpg" }],
},
},
});
isUse is to filter results by matching specific fields within composite types.
shippingAddress that matches the given street nameconst orders = await prisma.order.findMany({
where: {
shippingAddress: {
is: {
street: "555 Candy Cane Lane",
},
},
},
});
isNotUse isNot to filter results for composite type fields that do not match.
shippingAddress that does not match the given zip codeconst orders = await prisma.order.findMany({
where: {
shippingAddress: {
isNot: {
zip: "52337",
},
},
},
});
isEmptyUse isEmpty to filter results for an empty list of composite types.
const product = prisma.product.findMany({
where: {
photos: {
isEmpty: true,
},
},
});
everyUse every to filter for lists of composite types where every item in the list matches the condition
height of 200const product = await prisma.product.findFirst({
where: {
photos: {
every: {
height: 200,
},
},
},
});
someUse some to filter for lists of composite types where one or more items in the list match the condition.
url of 2.jpgconst product = await prisma.product.findFirst({
where: {
photos: {
some: {
url: "2.jpg",
},
},
},
});
noneUse none to filter for lists of composite types where no items in the list match the condition.
url of 2.jpgconst product = await prisma.product.findFirst({
where: {
photos: {
none: {
url: "2.jpg",
},
},
},
});
Atomic operations on update is available for number field types (Float and Int). This feature allows you to update a field based on its current value (such as subtracting or dividing) without risking a race condition.
A race conditions occurs when two or more operations must be done in sequence in order to complete a task. In the following example, two clients try to increase the same field (postCount) by one:
| Client | Operation | Value |
|---|---|---|
| Client 1 | Get field value | 21 |
| Client 2 | Get field value | 21 |
| Client 2 | Set field value | 22 |
| Client 1 | Set field value | 22 ✘ |
The value should be 23, but the two clients did not read and write to the postCount field in sequence. Atomic operations on update combine read and write into a single operation, which prevents a race condition:
| Client | Operation | Value |
|---|---|---|
| Client 1 | Get and set field value | 21 → 22 |
| Client 2 | Get and set field value | 22 → 23 ✔ |
| Option | Description |
|---|---|
increment | Adds n to the current value. |
decrement | Subtacts n from the current value. |
multiply | Multiplies the current value by n. |
divide | Divides the current value by n. |
set | Sets the current field value. Identical to { myField : n }. |
null, it will not be updated by increment, decrement, multiply, or divide.view and likes fields of all Post records by 1const updatePosts = await prisma.post.updateMany({
data: {
views: {
increment: 1,
},
likes: {
increment: 1,
},
},
});
views fields of all Post records to 0const updatePosts = await prisma.post.updateMany({
data: {
views: {
set: 0,
},
},
});
Can also be written as:
const updatePosts = await prisma.post.updateMany({
data: {
views: 0,
},
});
Json filtersFor use cases and advanced examples, see: Working with Json fields.
:::warning
Supported by PostgreSQL and MySQL with different syntaxes for the path option. PostgreSQL does not support filtering on object key values in arrays.
:::
The examples in this section assumes that the value of the pet field is:
{
"favorites": {
"catBreed": "Turkish van",
"dogBreed": "Rottweiler",
"sanctuaries": ["RSPCA", "Alley Cat Allies"],
"treats": [
{ "name": "Dreamies", "manufacturer": "Mars Inc" },
{ "name": "Treatos", "manufacturer": "The Dog People" }
]
},
"fostered": {
"cats": ["Bob", "Alice", "Svetlana the Magnificent", "Queenie"]
},
"owned": {
"cats": ["Elliott"]
}
}
Json filtering differs between database connectorsmodepathpath represents the location of a specific key. The following query returns all users where the nested favorites > dogBreed key equals "Rottweiler".
const getUsers = await prisma.user.findMany({
where: {
pets: {
path: ["favorites", "dogBreed"],
equals: "Rottweiler",
},
},
});
const getUsers = await prisma.user.findMany({
where: {
pets: {
path: "$.favorites.dogBreed",
equals: "Rottweiler",
},
},
});
The following query returns all users where the nested owned > cats array contains "Elliott".
const getUsers = await prisma.user.findMany({
where: {
pets: {
path: ["owned", "cats"],
array_contains: ["Elliott"],
},
},
});
const getUsers = await prisma.user.findMany({
where: {
pets: {
path: "$.owned.cats",
array_contains: "Elliott",
},
},
});
:::warning
Filtering by the key values of objects inside an array (below) is only supported by the MySQL connector.
:::
The following query returns all users where the nested favorites > treats array contains an object where the name value is "Dreamies":
const getUsers = await prisma.user.findMany({
where: {
pets: {
path: "$.favorites.treats[*].name",
array_contains: "Dreamies",
},
},
});
string_containsThe following query returns all users where the nested favorites > catBreed key value contains "Van":
const getUsers = await prisma.user.findMany({
where: {
pets: {
path: ["favorites", "catBreed"],
string_contains: "Van",
},
},
});
const getUsers = await prisma.user.findMany({
where: {
pets: {
path: "$.favorites.catBreed",
string_contains: "Van",
},
},
});
string_starts_withThe following query returns all users where the nested favorites > catBreed key value starts with "Turkish":
const getUsers = await prisma.user.findMany({
where: {
pets: {
path: ["favorites", "catBreed"],
string_starts_with: "Turkish",
},
},
});
const getUsers = await prisma.user.findMany({
where: {
pets: {
path: "$.favorites.catBreed",
string_starts_with: "Turkish",
},
},
});
string_ends_withThe following query returns all users where the nested favorites > catBreed key value ends with "Van":
const getUsers = await prisma.user.findMany({
where: {
pets: {
path: ["favorites", "catBreed"],
string_ends_with: "Van",
},
},
});
const getUsers = await prisma.user.findMany({
where: {
pets: {
path: "$.favorites.catBreed",
string_ends_with: "Van",
},
},
});
modeSpecify whether the string filtering should be case sensitive (default) or case insensitive.
The following query returns all users where the nested favorites > catBreed key value contains "Van" or "van":
const getUsers = await prisma.user.findMany({
where: {
pets: {
path: ["favorites", "catBreed"],
string_contains: "Van",
mode: "insensitive",
},
},
});
const getUsers = await prisma.user.findMany({
where: {
pets: {
path: "$.favorites.catBreed",
string_contains: "Van",
mode: "insensitive",
},
},
});
array_containsThe following query returns all users where the sanctuaries array contains the value "RSPCA":
const getUsers = await prisma.user.findMany({
where: {
pets: {
path: ["sanctuaries"],
array_contains: ["RSPCA"],
},
},
});
const getUsers = await prisma.user.findMany({
where: {
pets: {
path: "$.sanctuaries",
array_contains: "RSPCA",
},
},
});
:::info
In PostgreSQL, the value of array_contains must be an array and not a string, even if the array only contains a single value.
:::
The following query returns all users where the sanctuaries array contains all the values in the given array:
const getUsers = await prisma.user.findMany({
where: {
pets: {
path: ["sanctuaries"],
array_contains: ["RSPCA", "Alley Cat Allies"],
},
},
});
const getUsers = await prisma.user.findMany({
where: {
pets: {
path: "$.sanctuaries",
array_contains: ["RSPCA", "Alley Cat Allies"],
},
},
});
array_starts_withThe following query returns all users where the sanctuaries array starts with the value "RSPCA":
const getUsers = await prisma.user.findMany({
where: {
pets: {
path: ["sanctuaries"],
array_starts_with: "RSPCA",
},
},
});
const getUsers = await prisma.user.findMany({
where: {
pets: {
path: "$.sanctuaries",
array_starts_with: "RSPCA",
},
},
});
array_ends_withThe following query returns all users where the sanctuaries array ends with the value "Alley Cat Allies":
const getUsers = await prisma.user.findMany({
where: {
pets: {
path: ["sanctuaries"],
array_ends_with: "Alley Cat Allies",
},
},
});
const getUsers = await prisma.user.findMany({
where: {
pets: {
path: "$.sanctuaries",
array_ends_with: "Alley Cat Allies",
},
},
});
Note: Client-level methods are prefixed by $.
$on and $use client methods do not exist on extended client instances which are extended using $extends:::warning
In extended clients, Client methods do not necessarily exist. If you are extending your client, make sure to check for existence before using Client methods like $transaction or $connect.
In addition, if you are using $on or $use, you will need to use these client methods before extending your client as these methods do not exist on extended clients. For $use specifically we recommend transitioning to use query extensions.
:::
$disconnect()The $disconnect() method closes the database connections that were established when $connect was called and stops the process that was running Prisma ORM's query engine. See Connection management for an overview of $connect() and $disconnect().
$disconnect() returns a Promise, so you should call it inside an async function with the await keyword.$connect()The $connect() method establishes a physical connection to the database via Prisma ORM's query engine. See Connection management for an overview of $connect() and $disconnect().
$connect() returns a Promise, so you should call it inside an async function with the await keyword.$on():::warning
$on is not available in extended clients. Please either migrate to client extensions or use the $on method prior to extending your client.
:::
The $on() method allows you to subscribe to logging events or the exit hook.
$queryRawTypedSee: Using Raw SQL ($queryRawTyped).
$queryRawSee: Using Raw SQL ($queryRaw).
$queryRawUnsafe()See: Using Raw SQL ($queryRawUnsafe()).
$executeRawSee: Using Raw SQL ($executeRaw).
$executeRawUnsafe()See: Using Raw SQL ($executeRawUnsafe()).
$runCommandRaw()See: Using Raw SQL ($runCommandRaw()).
$transaction()See: Transactions.
$extendsWith $extends, you can create and use Prisma Client extensions to add functionality to Prisma Client in the following ways:
model: add custom methods to your modelsclient: add custom methods to your clientquery: create custom Prisma Client queriesresult: add custom fields to your query resultsLearn more: Prisma Client extensions.
Utility types are helper functions and types that live on the Prisma namespace. They are useful for keeping your application type safe.
satisfiesYou can use TypeScript's satisfies operator to create re-usable query parameters based on your schema models while ensuring that the objects you create are type-compatible with the generated Prisma Client types. See also: Type safety with Prisma Client.
Use the generated Prisma Client types with satisfies to get type checking and inference:
const args = { ... } satisfies Prisma.GeneratedType;
The following example shows how you can create type-checked input for the create operation that you can reuse within your app:
import { Prisma } from "../prisma/generated/client";
const createUserAndPostInput = (
name: string,
email: string,
postTitle: string,
) =>
({
name,
email,
posts: {
create: {
title: postTitle,
},
},
}) satisfies Prisma.UserCreateInput;
You can compare columns in the same table directly, for non-unique filters.
:::info
In the following situations, you must use raw queries to compare columns in the same table:
findUnique or findUniqueOrThrowgt, gte, lt, or lte. Note that you can use these operators to compare the JSON field with a scalar value. This limitation applies only if you try to compare a JSON field with another field.:::
To compare columns in the same table, use the <model>.fields property. In the following example, the query returns all records where the value in the prisma.product.quantity field is less than or equal to the value in the prisma.product.warnQuantity field.
prisma.product.findMany({
where: { quantity: { lte: prisma.product.fields.warnQuantity } },
});
:::info
fields is a special property of every model. It contains the list of fields for that model.
:::
You can only make comparisons on fields of the same type. For example, the following causes an error:
await prisma.order.findMany({
where: {
id: { equals: prisma.order.fields.due },
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
// Type error: id is a string, while amountDue is an integer
},
});
You can only make comparisons with the fields property on fields in the same model. The following example does not work:
await prisma.order.findMany({
where: {
id: { equals: prisma.user.fields.name },
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
// Type error: name is a field on the User model, not Order
},
});
However, you can compare fields in separate models with standard queries.
groupBy model queries, put your referenced fields in the by argumentIf you use the groupBy model query with the having option, then you must put your referenced fields in the by argument.
The following example works:
prisma.user.groupBy({
by: ["id", "name"],
having: { id: { equals: prisma.user.fields.name } },
});
The following example does not work, because name is not in the by argument:
prisma.user.groupBy({
by: ["id"],
having: { id: { equals: prisma.user.fields.name } },
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
// name is not in the 'by' argument
});
If your data source supports scalar lists (for example in PostgreSQL), then you can search for all records where a specific field is in a list of fields. To do so, reference the scalar list with the in and notIn filters. For example:
await prisma.user.findMany({
where: {
// find all users where 'name' is in a list of tags
name: { in: prisma.user.fields.tags },
},
});
UserWhereUniqueInputThe generated type UserWhereUniqueInput on where exposes all fields on the model, not just unique fields.
You must specify at least one unique field in your where statement outside of boolean operators, and you can specify any number of additional unique and non-unique fields. You can use this to add filters to any operation that returns a single record. For example, you can use this feature for the following:
You can filter on non-unique fields to perform optimistic concurrency control on update operations.
To perform optimistic concurrency control, use a version field to check whether the data in a record or related record has changed while your code executes.
In the following example, updateOne and updateTwo first read the same record and then attempt to update it. The database only executes these updates if the value in version is the same as the value when it did the initial read. When the database executes the first of these updates (which might be updateOne or updateTwo, depending on timing), it increments the value in version. This means that the database does not execute the second update because the value in version has changed.
model User {
id Int @id @default(autoincrement())
email String @unique
city String
version Int
}
function updateOne() {
const user = await prisma.user.findUnique({ id: 1 });
await prisma.user.update({
where: { id: user.id, version: user.version },
data: { city: "Berlin", version: { increment: 1 } },
});
}
function updateTwo() {
const user = await prisma.user.findUnique({ id: 1 });
await prisma.user.update({
where: { id: user.id, version: user.version },
data: { city: "New York", version: { increment: 1 } },
});
}
function main() {
await Promise.allSettled([updateOne(), updateTwo()]);
}
You can filter on non-unique fields to check permissions during an update.
In the following example, a user wants to update a post title. The where statement checks the value in authorId to confirm that the user is the author of the post. The application only updates the post title if the user is the post author.
await prisma.post.update({
where: { id: 1, authorId: 1 },
data: { title: "Updated post title" },
});
You can filter on non-unique fields to handle soft deletes.
In the following example, we do not want to return a post if it is soft-deleted. The operation only returns the post if the value in isDeleted is false.
prisma.Post.findUnique({ where: { id: postId, isDeleted: false } });
UserWhereUniqueInput considerationsUserWhereUniqueInputWith UserWhereUniqueInput, you must specify at least one unique field outside of the boolean operators AND, OR, NOT. You can still use these boolean operators in conjunction with any other unique fields or non-unique fields in your filter.
In the following example, we test id, a unique field, in conjunction with email. This is valid.
await prisma.user.update({
where: { id: 1, OR: [{ email: "[email protected]" }, { email: "[email protected]" }] },
// ^^^ Valid: the expression specifies a unique field (`id`) outside of any boolean operators
data: { ... }
})
// SQL equivalent:
// WHERE id = 1 AND (email = "[email protected]" OR email = "[email protected]")
The following example is not valid, because there is no unique field outside of any boolean operators:
await prisma.user.update({
where: { OR: [{ email: "[email protected]" }, { email: "[email protected]" }] },
// ^^^ Invalid: the expressions does not contain a unique field outside of boolean operators
data: { ... }
})
You can filter on non-unique fields in the following operations on one-to-one relations:
Prisma Client automatically uses a unique filter to select the appropriate related record. As a result, you do not need to specify a unique filter in your where statement with a WhereUniqueInput generated type. Instead, the where statement has a WhereInput generated type. You can use this to filter without the restrictions of WhereUniqueInput.
await prisma.user.update({
where: { id: 1 },
data: {
to_one: {
update: { where: { /* WhereInput */ }, data: { field: "updated" } }
}
}
})
await prisma.user.update({
where: { id: 1 },
data: {
to_one: {
upsert: {
where: { /* WhereInput */ },
create: { /* CreateInput */ },
update: { /* UpdateInput */ },
}
}
}
})
await prisma.user.update({
where: { id: 1 },
data: {
to_one: {
disconnect: { /* WhereInput */ }
}
}
})
await prisma.user.update({
where: { id: 1 },
data: {
to_one: {
delete: { /* WhereInput */ }
}
}
})
PrismaPromise behaviorAll Prisma Client queries return an instance of PrismaPromise. This is a "thenable", meaning a PrismaPromise only executes when you call await or .then() or .catch(). This behavior is different from a regular JavaScript Promise, which starts executing immediately.
For example:
const findPostOperation = prisma.post.findMany({}); // Query not yet executed
findPostOperation.then(); // Prisma Client now executes the query
// or
await findPostOperation; // Prisma Client now executes the query
When using the $transaction API, this behavior makes it possible for Prisma Client to pass all the queries on to the query engine as a single transaction.