CRUD (Reference) | Prisma Documentation (2024)

This page describes how to perform CRUD operations with your generated Prisma Client API. CRUD is an acronym that stands for:

  • Create
  • Read
  • Update
  • Delete

Refer to the Prisma Client API reference documentation for detailed explanations of each method.

Example schema

All examples are based on the following schema:

Expand for sample schema
  • Relational databases
  • MongoDB
datasource db {
provider = "postgresql"
url = env("DATABASE_URL")
}

generator client {
provider = "prisma-client-js"
}

model ExtendedProfile {
id Int @id @default(autoincrement())
biography String
user User @relation(fields: [userId], references: [id])
userId Int @unique
}

model User {
id Int @id @default(autoincrement())
name String?
email String @unique
profileViews Int @default(0)
role Role @default(USER)
coinflips Boolean[]
posts Post[]
profile ExtendedProfile?
}

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)
categories Category[]
}

model Category {
id Int @id @default(autoincrement())
name String @unique
posts Post[]
}

enum Role {
USER
ADMIN
}

For relational databases, use db push command to push the example schema to your own database

npx prisma db push

For MongoDB, ensure your data is in a uniform shape and matches the model defined in the Prisma schema.

Create

Create a single record

The following query creates (create()) a single user with two fields:

const user = await prisma.user.create({
data: {
email: 'elsa@prisma.io',
name: 'Elsa Prisma',
},
})

Show

query

results

The user's id is auto-generated, and your schema determines which fields are mandatory.

Create a single record using generated types

The following example produces an identical result, but creates a UserCreateInput variable named user outside the context of the create() query. After completing a simple check ("Should posts be included in this create() query?"), the user variable is passed into the query:

import { PrismaClient, Prisma } from '@prisma/client'

const prisma = new PrismaClient()

async function main() {
let includePosts: boolean = false
let user: Prisma.UserCreateInput

// Check if posts should be included in the query
if (includePosts) {
user = {
email: 'elsa@prisma.io',
name: 'Elsa Prisma',
posts: {
create: {
title: 'Include this post!',
},
},
}
} else {
user = {
email: 'elsa@prisma.io',
name: 'Elsa Prisma',
}
}

// Pass 'user' object into query
const createUser = await prisma.user.create({ data: user })
}

main()

For more information about working with generated types, see: Generated types.

Create multiple records

Prisma Client supports bulk inserts as a GA feature in 2.20.0 and later.

The following createMany() query creates multiple users and skips any duplicates (email must be unique):

const createMany = await prisma.user.createMany({
data: [
{ name: 'Bob', email: 'bob@prisma.io' },
{ name: 'Bobo', email: 'bob@prisma.io' }, // Duplicate unique key!
{ name: 'Yewande', email: 'yewande@prisma.io' },
{ name: 'Angelique', email: 'angelique@prisma.io' },
],
skipDuplicates: true, // Skip 'Bobo'
})

Show

query

results

warning

Note skipDuplicates is not supported when using MongoDB, SQLServer, or SQLite.

createMany() uses a single INSERT INTO statement with multiple values, which is generally more efficient than a separate INSERT per row:

BEGIN
INSERT INTO "public"."User" ("id","name","email","profileViews","role","coinflips","testing","city","country") VALUES (DEFAULT,$1,$2,$3,$4,DEFAULT,DEFAULT,DEFAULT,$5), (DEFAULT,$6,$7,$8,$9,DEFAULT,DEFAULT,DEFAULT,$10), (DEFAULT,$11,$12,$13,$14,DEFAULT,DEFAULT,DEFAULT,$15), (DEFAULT,$16,$17,$18,$19,DEFAULT,DEFAULT,DEFAULT,$20) ON CONFLICT DO NOTHING
COMMIT
SELECT "public"."User"."country", "public"."User"."city", "public"."User"."email", SUM("public"."User"."profileViews"), COUNT(*) FROM "public"."User" WHERE 1=1 GROUP BY "public"."User"."country", "public"."User"."city", "public"."User"."email" HAVING AVG("public"."User"."profileViews") >= $1 ORDER BY "public"."User"."country" ASC OFFSET $2

Note: Multiple create() statements inside a $transaction results in multiple INSERT statements.

The following video demonstrates how to use createMany() and faker.js to seed a database with sample data:

Create records and connect or create related records

See Working with relations > Nested writes for information about creating a record and one or more related records at the same time.

Create and return multiple records

info

This feature is available in Prisma ORM version 5.14.0 and later for PostgreSQL, co*ckroachDB and SQLite.

You can use createManyAndReturn() in order to create many records and return the resulting objects.

const users = await prisma.user.createManyAndReturn({
data: [
{ name: 'Alice', email: 'alice@prisma.io' },
{ name: 'Bob', email: 'bob@prisma.io' },
],
})

Show

query

results

warning

relationLoadStrategy: join is not available when using createManyAndReturn().

Read

Get record by ID or unique identifier

The following queries return a single record (findUnique()) by unique identifier or ID:

// By unique identifier
const user = await prisma.user.findUnique({
where: {
email: 'elsa@prisma.io',
},
})

// By ID
const user = await prisma.user.findUnique({
where: {
id: 99,
},
})

If you are using the MongoDB connector and your underlying ID type is ObjectId, you can use the string representation of that ObjectId:

// By ID
const user = await prisma.user.findUnique({
where: {
id: '60d5922d00581b8f0062e3a8',
},
})

Get all records

The following findMany() query returns all User records:

const users = await prisma.user.findMany()

You can also paginate your results.

Get the first record that matches a specific criteria

The following findFirst() query returns the most recently created user with at least one post that has more than 100 likes:

  1. Order users by descending ID (largest first) - the largest ID is the most recent
  2. Return the first user in descending order with at least one post that has more than 100 likes
const findUser = await prisma.user.findFirst({
where: {
posts: {
some: {
likes: {
gt: 100,
},
},
},
},
orderBy: {
id: 'desc',
},
})

Get a filtered list of records

Prisma Client supports filtering on record fields and related record fields.

Filter by a single field value

The following query returns all User records with an email that ends in "prisma.io":

const users = await prisma.user.findMany({
where: {
email: {
endsWith: 'prisma.io',
},
},
})

Filter by multiple field values

The following query uses a combination of operators to return users whose name start with E or administrators with at least 1 profile view:

const users = await prisma.user.findMany({
where: {
OR: [
{
name: {
startsWith: 'E',
},
},
{
AND: {
profileViews: {
gt: 0,
},
role: {
equals: 'ADMIN',
},
},
},
],
},
})

Filter by related record field values

The following query returns users with an email that ends with prisma.io and have at least one post (some) that is not published:

const users = await prisma.user.findMany({
where: {
email: {
endsWith: 'prisma.io',
},
posts: {
some: {
published: false,
},
},
},
})

See Working with relations for more examples of filtering on related field values.

Select a subset of fields

The following findUnique() query uses select to return the email and name fields of a specific User record:

const user = await prisma.user.findUnique({
where: {
email: 'emma@prisma.io',
},
select: {
email: true,
name: true,
},
})

Show

query

results

For more information about including relations, refer to:

  • Select fields
  • Relation queries

Select a subset of related record fields

The following query uses a nested select to return:

  • The user's email
  • The likes field of each post
const user = await prisma.user.findUnique({
where: {
email: 'emma@prisma.io',
},
select: {
email: true,
posts: {
select: {
likes: true,
},
},
},
})

Show

query

results

For more information about including relations, see Select fields and include relations.

Select distinct field values

See Select distinct for information about selecting distinct field values.

Include related records

The following query returns all ADMIN users and includes each user's posts in the result:

const users = await prisma.user.findMany({
where: {
role: 'ADMIN',
},
include: {
posts: true,
},
})

Show

query

results

For more information about including relations, see Select fields and include relations.

Include a filtered list of relations

See Working with relations to find out how to combine include and where for a filtered list of relations - for example, only include a user's published posts.

Update

Update a single record

The following query uses update() to find and update a single User record by email:

const updateUser = await prisma.user.update({
where: {
email: 'viola@prisma.io',
},
data: {
name: 'Viola the Magnificent',
},
})

Show

query

results

Update multiple records

The following query uses updateMany() to update all User records that contain prisma.io:

const updateUsers = await prisma.user.updateMany({
where: {
email: {
contains: 'prisma.io',
},
},
data: {
role: 'ADMIN',
},
})

Show

query

results

Update or create records

The following query uses upsert() to update a User record with a specific email address, or create that User record if it does not exist:

const upsertUser = await prisma.user.upsert({
where: {
email: 'viola@prisma.io',
},
update: {
name: 'Viola the Magnificent',
},
create: {
email: 'viola@prisma.io',
name: 'Viola the Magnificent',
},
})

Show

query

results

info

From version 4.6.0, Prisma Client carries out upserts with database native SQL commands where possible. Learn more.

Prisma Client does not have a findOrCreate() query. You can use upsert() as a workaround. To make upsert() behave like a findOrCreate() method, provide an empty update parameter to upsert().

warning

A limitation to using upsert() as a workaround for findOrCreate() is that upsert() will only accept unique model fields in the where condition. So it's not possible to use upsert() to emulate findOrCreate() if the where condition contains non-unique fields.

Update a number field

Use atomic number operations to update a number field based on its current value - for example, increment or multiply. The following query increments the views and likes fields by 1:

const updatePosts = await prisma.post.updateMany({
data: {
views: {
increment: 1,
},
likes: {
increment: 1,
},
},
})

Connect and disconnect related records

Refer to Working with relations for information about disconnecting (disconnect) and connecting (connect) related records.

Delete

Delete a single record

The following query uses delete() to delete a single User record:

const deleteUser = await prisma.user.delete({
where: {
email: 'bert@prisma.io',
},
})

Attempting to delete a user with one or more posts result in an error, as every Post requires an author - see cascading deletes.

Delete multiple records

The following query uses deleteMany() to delete all User records where email contains prisma.io:

const deleteUsers = await prisma.user.deleteMany({
where: {
email: {
contains: 'prisma.io',
},
},
})

Attempting to delete a user with one or more posts result in an error, as every Post requires an author - see cascading deletes.

Delete all records

The following query uses deleteMany() to delete all User records:

const deleteUsers = await prisma.user.deleteMany({})

Be aware that this query will fail if the user has any related records (such as posts). In this case, you need to delete the related records first.

Cascading deletes (deleting related records)

warning

In 2.26.0 and later it is possible to do cascading deletes using the preview feature referential actions.

The following query uses delete() to delete a single User record:

const deleteUser = await prisma.user.delete({
where: {
email: 'bert@prisma.io',
},
})

However, the example schema includes a required relation between Post and User, which means that you cannot delete a user with posts:

The change you are trying to make would violate the required relation 'PostToUser' between the `Post` and `User` models.

To resolve this error, you can:

  • Make the relation optional:

    model Post {
    id Int @id @default(autoincrement())
    author User? @relation(fields: [authorId], references: [id])
    authorId Int?
    author User @relation(fields: [authorId], references: [id])
    authorId Int
    }
  • Change the author of the posts to another user before deleting the user.

  • Delete a user and all their posts with two separate queries in a transaction (all queries must succeed):

    const deletePosts = prisma.post.deleteMany({
    where: {
    authorId: 7,
    },
    })

    const deleteUser = prisma.user.delete({
    where: {
    id: 7,
    },
    })

    const transaction = await prisma.$transaction([deletePosts, deleteUser])

Delete all records from all tables

Sometimes you want to remove all data from all tables but keep the actual tables. This can be particularly useful in a development environment and whilst testing.

The following shows how to delete all records from all tables with Prisma Client and with Prisma Migrate.

Deleting all data with deleteMany()

When you know the order in which your tables should be deleted, you can use the deleteMany function. This is executed synchronously in a $transaction and can be used with all types of databases.

const deletePosts = prisma.post.deleteMany()
const deleteProfile = prisma.profile.deleteMany()
const deleteUsers = prisma.user.deleteMany()

// The transaction runs synchronously so deleteUsers must run last.
await prisma.$transaction([deleteProfile, deletePosts, deleteUsers])

Pros:

  • Works well when you know the structure of your schema ahead of time
  • Synchronously deletes each tables data

Cons:

  • When working with relational databases, this function doesn't scale as well as having a more generic solution which looks up and TRUNCATEs your tables regardless of their relational constraints. Note that this scaling issue does not apply when using the MongoDB connector.

Note: The $transaction performs a cascading delete on each models table so they have to be called in order.

Deleting all data with raw SQL / TRUNCATE

If you are comfortable working with raw SQL you can perform a TRUNCATE on a table by utilizing $executeRawUnsafe.

In the following examples, the first tab shows how to perform a TRUNCATE on a Postgres database by using a $queryRaw look up that maps over the table and TRUNCATES all tables in a single query.

The second tab shows performing the same function but with a MySQL database. In this instance the constraints must be removed before the TRUNCATE can be executed, before being reinstated once finished. The whole process is run as a $transaction

  • PostgreSQL
  • MySQL
const tablenames = await prisma.$queryRaw<
Array<{ tablename: string }>
>`SELECT tablename FROM pg_tables WHERE schemaname='public'`

const tables = tablenames
.map(({ tablename }) => tablename)
.filter((name) => name !== '_prisma_migrations')
.map((name) => `"public"."${name}"`)
.join(', ')

try {
await prisma.$executeRawUnsafe(`TRUNCATE TABLE ${tables} CASCADE;`)
} catch (error) {
console.log({ error })
}

Pros:

  • Scalable
  • Very fast

Cons:

  • Can't undo the operation
  • Using reserved SQL key words as tables names can cause issues when trying to run a raw query

Deleting all records with Prisma Migrate

If you use Prisma Migrate, you can use migrate reset, this will:

  1. Drop the database
  2. Create a new database
  3. Apply migrations
  4. Seed the database with data

Advanced query examples

Create a deeply nested tree of records

  • A single User
  • Two new, related Post records
  • Connect or create Category per post
const u = await prisma.user.create({
include: {
posts: {
include: {
categories: true,
},
},
},
data: {
email: 'emma@prisma.io',
posts: {
create: [
{
title: 'My first post',
categories: {
connectOrCreate: [
{
create: { name: 'Introductions' },
where: {
name: 'Introductions',
},
},
{
create: { name: 'Social' },
where: {
name: 'Social',
},
},
],
},
},
{
title: 'How to make cookies',
categories: {
connectOrCreate: [
{
create: { name: 'Social' },
where: {
name: 'Social',
},
},
{
create: { name: 'Cooking' },
where: {
name: 'Cooking',
},
},
],
},
},
],
},
},
})
CRUD (Reference) | Prisma Documentation (2024)

FAQs

Is Prisma safe to use? ›

Prisma ORM is the only fully type-safe ORM in the TypeScript ecosystem. The generated Prisma Client ensures typed query results even for partial queries and relations. You can learn more about this in the type-safety comparison with TypeORM.

What is the difference between findUnique and findFirst? ›

As you can immagine, these two methods allow us to retrieve a single record. The findFirst is like the findMany but it returns the first record of the result. The findUnique otherwise returns a record by its key.

How to update data with Prisma? ›

To update data with Prisma Client, issue an update query. Prisma is an open-source database toolkit for Typescript and Node. js that aims to make app developers more productive and confident when working with databases.

What is upsert prisma? ›

Use upsert to update or create records depending on whether it already exists or not. The examples use the following prisma schema: model Post { id String @id @default(cuid()) createdAt DateTime @default(now()) updatedAt DateTime @updatedAt published Boolean title String content String?

Why is Prisma so popular? ›

Prisma ORM's main goal is to make application developers more productive when working with databases. Here are a few examples of how Prisma ORM achieves this: Thinking in objects instead of mapping relational data. Queries not classes to avoid complex model objects.

Is Prisma ORM bad? ›

If you're unfamiliar, Prisma is a well-known TypeScript ORM for PostgreSQL and MongoDB. It was the first ORM I learned to use, and this decision led to some difficulties later on. Prisma's primary issue is that its entity creation and database modeling only work with their own language.

Is findAny faster than findFirst? ›

Another important difference is that findFirst() is typically faster than findAny() when used with sequential streams, because it only needs to examine the first element in the stream. However, with parallel streams, findAny() may be faster in some cases because it can process multiple elements in parallel.

What is the difference between Qsort and Qsort_r? ›

The qsort_r() function shall be identical to qsort() except that the comparison function compar takes a third argument. The arg opaque pointer passed to qsort_r() shall in turn be passed as the third argument to the comparison function.

What is the difference between Treesort and quicksort? ›

Tree sort can be used as a one-time sort, but it is equivalent to quicksort as both recursively partition the elements based on a pivot, and since quicksort is in-place and has lower overhead, tree sort has few advantages over quicksort.

Is prisma data free? ›

No, there are no payments required. Our open-source ORM is and will remain free.

How do you check if data exists in prisma? ›

The Prisma client lets you check whether a certain record exists in the database using the $exists property. For each model type in your datamodel, the Prisma client exposes one function on this property named after the model (but lowercased).

Does prisma cache data? ›

When a read query is executed, if the cached response is within the ttl limit, Prisma Client retrieves the data from the cache without querying the database. If the cached data is not available or has expired, Prisma Client queries the database and stores the results in the cache for future requests.

What is the difference between Prisma access and Prisma cloud? ›

In the Cloud Security market, Prisma Cloud has a 0.03% market share in comparison to Prisma Access's 0.01%. Since it has a better market share coverage, Prisma Cloud holds the 15th spot in 6sense's Market Share Ranking Index for the Cloud Security category, while Prisma Access holds the 24th spot.

Is Prisma asynchronous? ›

The compute function in Prisma Client $extends method does not support asynchronous operations. It is designed to be synchronous and does not support Promises or async/await syntax.

Is Prisma a ORM? ›

Prisma is an ORM focused on making it easy for Node. js and TypeScript applications to work with databases.

Is Prisma type-safe? ›

Type utilities​

To help you create highly type-safe applications, Prisma Client provides a set of type utilities that tap into input and output types. These types are fully dynamic, which means that they adapt to any given model and schema.

Does Prisma own your photos? ›

Your original content and your edited content belong to you, and we claim no ownership over it. You would need to give us a permission to use that content (e.g., for our AI to edit your photos). Prisma allows you to upload, edit, create, store, and share content, including photos (“User Content”).

What does Prisma do for a wound? ›

PROMOGRAN PRISMA™ Matrix, when covered with a semi-occlusive dressing, like a foam, maintains a moist wound environment. This environment is conducive to granulation tissue formation, epithelialization and optimal wound healing. The silver in PROMOGRAN PRISMA™ Matrix helps provide a barrier to bacteria in the dressing.

How long can Prisma stay on? ›

It is not necessary to remove any residual PROMOGRAN PRISMA® Matrix during dressing changes as it will be naturally absorbed into the body over time. 2. After initial treatment, retreat the wound with PROMOGRAN PRISMA® Matrix up to every 72 hours depending upon the amount of exudate.

References

Top Articles
Basketball Stars Unblocked 66 Ez
Cetaphil Samples For Providers
Spasa Parish
Rentals for rent in Maastricht
159R Bus Schedule Pdf
Sallisaw Bin Store
Black Adam Showtimes Near Maya Cinemas Delano
Espn Transfer Portal Basketball
Pollen Levels Richmond
11 Best Sites Like The Chive For Funny Pictures and Memes
Things to do in Wichita Falls on weekends 12-15 September
Craigslist Pets Huntsville Alabama
Paulette Goddard | American Actress, Modern Times, Charlie Chaplin
What's the Difference Between Halal and Haram Meat & Food?
R/Skinwalker
Rugged Gentleman Barber Shop Martinsburg Wv
Jennifer Lenzini Leaving Ktiv
Justified - Streams, Episodenguide und News zur Serie
Epay. Medstarhealth.org
Olde Kegg Bar & Grill Portage Menu
Cubilabras
Half Inning In Which The Home Team Bats Crossword
Amazing Lash Bay Colony
Juego Friv Poki
Dirt Devil Ud70181 Parts Diagram
Truist Bank Open Saturday
Water Leaks in Your Car When It Rains? Common Causes & Fixes
What’s Closing at Disney World? A Complete Guide
New from Simply So Good - Cherry Apricot Slab Pie
Drys Pharmacy
Ohio State Football Wiki
FirstLight Power to Acquire Leading Canadian Renewable Operator and Developer Hydromega Services Inc. - FirstLight
Webmail.unt.edu
2024-25 ITH Season Preview: USC Trojans
Metro By T Mobile Sign In
Restored Republic December 1 2022
12 30 Pacific Time
Jami Lafay Gofundme
Litter-Robot 3 Pinch Contact & Dfi Kit
Greenbrier Bunker Tour Coupon
No Compromise in Maneuverability and Effectiveness
Black Adam Showtimes Near Cinemark Texarkana 14
Teamnet O'reilly Login
U-Haul Hitch Installation / Trailer Hitches for Towing (UPDATED) | RV and Playa
Wie blocke ich einen Bot aus Boardman/USA - sellerforum.de
Infinity Pool Showtimes Near Maya Cinemas Bakersfield
Hooda Math—Games, Features, and Benefits — Mashup Math
Dermpathdiagnostics Com Pay Invoice
How To Use Price Chopper Points At Quiktrip
Maria Butina Bikini
Busted Newspaper Zapata Tx
Latest Posts
Article information

Author: Greg O'Connell

Last Updated:

Views: 5229

Rating: 4.1 / 5 (42 voted)

Reviews: 81% of readers found this page helpful

Author information

Name: Greg O'Connell

Birthday: 1992-01-10

Address: Suite 517 2436 Jefferey Pass, Shanitaside, UT 27519

Phone: +2614651609714

Job: Education Developer

Hobby: Cooking, Gambling, Pottery, Shooting, Baseball, Singing, Snowboarding

Introduction: My name is Greg O'Connell, I am a delightful, colorful, talented, kind, lively, modern, tender person who loves writing and wants to share my knowledge and understanding with you.