Prisma - Update and Delete Operations
Prisma - Update and Delete Operations

Prisma - Update and Delete Operations

in
  1. Update Operations
    1. Updating a Single Record
    2. Batch Update
    3. Relation-Based Updates
  2. Delete Operations
    1. Deleting a Single Record
    2. Batch Delete
    3. Relation-Based Deletion (Cascade Delete)
  3. References

In the previous blog, we introduced Prisma as a modern ORM solution for TypeScript and demonstrated how to perform basic data insertion and query operations. In this article, we will further explore how to execute update and delete operations using Prisma.

Update Operations

Update operations allow you to modify existing records in the database. Prisma provides multiple ways to update data, including updating a single record, batch updates, and conditional updates. The following examples illustrate these operations in detail.

Updating a Single Record

To update a single record, you can use the update method, specifying the update condition and the data fields to modify.

import { PrismaClient } from '@prisma/client'

const prisma = new PrismaClient()

async function updateUser() {
  const updatedUser = await prisma.user.update({
    where: { email: 'alice@example.com' },
    data: { name: 'Alice Updated' },
  })
  console.log('Updated user:', updatedUser)
}

updateUser()
  .catch(e => {
    throw e
  })
  .finally(async () => {
    await prisma.$disconnect()
  })

After running this code, the updated user information will be printed:

Updated user: { id: 1, name: 'Alice Updated', email: 'alice@example.com' }

Batch Update

If you need to update multiple records at once, you can use the updateMany method. This method allows you to batch update data based on conditions.

import {PrismaClient} from '@prisma/client'

const prisma = new PrismaClient()

async function updateMultipleUsers() {
  const result = await prisma.post.updateMany({
    where: {
      author: {
        email: {
          equals: 'bob@example.com'
        }
      }
    },
    data: {published: true},
  });
  console.log(`Updated ${result.count} posts`)
  await prisma.post.findMany({
    where: {
      published: true
    }
  }).then(posts => {
    console.log(posts)
  });
}

updateMultipleUsers()
  .catch(e => {
    throw e
  })
  .finally(async () => {
    await prisma.$disconnect()
  })

After running, it prints the number of updated posts:

Updated 2 posts
[
  {
    id: 1,
    title: 'My First Post',
    content: 'This is the content',
    published: true,
    authorId: 2
  },
  {
    id: 2,
    title: 'My Second Post',
    content: 'More content',
    published: true,
    authorId: 2
  }
]

Relation-Based Updates

Prisma also allows you to update related records while updating a parent record. For example, updating a user and their associated posts:

import {PrismaClient} from '@prisma/client'

const prisma = new PrismaClient()

async function updateUserWithPosts() {
  const updatedUser = await prisma.user.update({
    where: { email: 'bob@example.com' },
    data: {
      name: 'Bob Updated',
      posts: {
        updateMany: {
          where: { title: 'My First Post' },
          data: { published: false },
        },
      },
    },
    include: { posts: true },
  })
  console.log('Updated user and their posts:', updatedUser)
}

updateUserWithPosts()
  .catch(e => {
    throw e
  })
  .finally(async () => {
    await prisma.$disconnect()
  })

The output:

Updated user and their posts: {
  id: 2,
  name: 'Bob Updated',
  email: 'bob@example.com',
  posts: [
    {
      id: 1,
      title: 'My First Post',
      content: 'This is the content',
      published: false,
      authorId: 2
    },
    {
      id: 2,
      title: 'My Second Post',
      content: 'More content',
      published: true,
      authorId: 2
    }
  ]
}

Delete Operations

Delete operations allow you to remove records from the database that you no longer need. Prisma provides several deletion methods, including single deletion and batch deletion. The following examples explain these operations in detail.

Deleting a Single Record

To delete a single record, use the delete method with the deletion condition:

async function deleteUser() {
  const deletedUser = await prisma.user.delete({
    where: { email: 'alice@example.com' },
  })
  console.log('Deleted user:', deletedUser)
}

deleteUser()
  .catch(e => {
    throw e
  })
  .finally(async () => {
    await prisma.$disconnect()
  })

Output:

Deleted user: { id: 1, name: 'Alice Updated', email: 'alice@example.com' }

Batch Delete

If you need to delete multiple records, use deleteMany. This method deletes data based on conditions.

async function deleteMultipleUsers() {
  const result = await prisma.user.deleteMany({
    where: { email: { contains: '@example.com' } },
  })
  console.log(`Deleted ${result.count} users`)
}

However, the above code will first throw a Foreign key constraint violated: 'foreign key' error because related posts still exist. Therefore, we must delete the posts first:

import {PrismaClient} from '@prisma/client'

const prisma = new PrismaClient()

async function deleteMultipleUsers() {
  const deletedEmail = "@example.com"
  const post_result = await prisma.post.deleteMany({
    where: { author: { email: { contains: deletedEmail } } },
  })
  const user_result = await prisma.user.deleteMany({
    where: { email: { contains: deletedEmail } },
  })
  console.log(`Deleted ${post_result.count} posts and ${user_result.count} users`)
}

deleteMultipleUsers()
  .catch(e => {
    throw e
  })
  .finally(async () => {
    await prisma.$disconnect()
  })

Output:

Deleted 2 posts and 1 user

Relation-Based Deletion (Cascade Delete)

When dealing with relational data, delete operations require care. Besides deleting manually, Prisma supports cascade deletes. If cascade behavior is configured in your data model, related records are automatically removed when the parent record is deleted.

model Post {
  id        Int     @id @default(autoincrement())
  title     String
  content   String?
  published Boolean @default(false)
  authorId  Int
  author    User    @relation(fields: [authorId], references: [id], onDelete: Cascade)
}

This way, when deleting a user, all their posts will also be deleted.

import {PrismaClient} from '@prisma/client'

const prisma = new PrismaClient()

async function deleteUserWithCascade() {
  const deletedUser = await prisma.user.delete({
    where: { email: 'bob@example.com' },
    include: { posts: true },
  })
  console.log('Deleted user:', deletedUser)

  // Verify that associated posts are removed
  const userPosts = await prisma.post.findMany({
    where: { authorId: deletedUser.id },
  })
  console.log('Remaining associated posts:', userPosts.length)
}

deleteUserWithCascade()
  .catch(e => {
    console.error(e)
  })
  .finally(async () => {
    await prisma.$disconnect()
  })

Output:

Deleted user: {
  id: 8,
  name: 'Bob',
  email: 'bob@example.com',
  posts: [
    {
      id: 7,
      title: 'My First Post',
      content: 'This is the content',
      published: true,
      authorId: 8
    },
    {
      id: 8,
      title: 'My Second Post',
      content: 'More content',
      published: false,
      authorId: 8
    }
  ]
}
Remaining associated posts: 0

References