CodingNic

CRUD and Querying with Prisma

Writing Data

CRUD and Querying with Prisma 15 min read

Writing Data

Objectives

By the end of this lesson, you should be able to:

  • Create, update, and delete records with Prisma Client
  • Use updateMany and deleteMany for bulk operations
  • Choose the right write method for a given situation

💡 Why this matters: Lesson 1 covered reading, this lesson covers the other three-quarters of CRUD, the direct replacement for the INSERT, UPDATE, and DELETE statements written by hand in Module 2.

⚠️ A note on verification: as throughout this module, the Prisma CLI can’t run inside this course’s own sandboxed tooling. The code below reflects Prisma Client’s stable, current, documented query API. Try it yourself, on your own machine, against a real database.

create

javascript
const student = await prisma.student.create({
  data: { name: 'Maya', grade: 9 }
});
console.log(student);
text
{ id: 3, name: 'Maya', grade: 9 }

Equivalent to INSERT ... RETURNING * from Module 2, create always returns the full created row, including the auto-generated id.

update

javascript
const updated = await prisma.student.update({
  where: { id: 3 },
  data: { grade: 10 }
});
console.log(updated);
text
{ id: 3, name: 'Maya', grade: 10 }

update requires a unique where (an id, or any @unique field), it updates exactly one row, and throws an error if no row matches, unlike raw SQL’s UPDATE, which silently affects zero rows if nothing matches.

delete

javascript
const deleted = await prisma.student.delete({
  where: { id: 3 }
});
console.log(deleted);

const remaining = await prisma.student.findMany();
console.log(remaining);
text
{ id: 3, name: 'Maya', grade: 10 }
[ { id: 1, name: 'Erin', grade: 9 }, { id: 2, name: 'Jordan', grade: 10 } ]

delete also requires a unique where, and returns the row that was deleted.

Bulk Operations: updateMany and deleteMany

For changing or removing more than one row at once, update and delete aren’t the right tool, they need updateMany and deleteMany, which accept any where, not just a unique one:

javascript
const result = await prisma.student.updateMany({
  where: { grade: 9 },
  data: { grade: 10 }
});
console.log(result);
text
{ count: 1 }

Unlike update, updateMany doesn’t return the updated rows, only a count, the same information rowCount gave in Module 2’s raw SQL. The same pattern applies to deleteMany:

javascript
const deletedCount = await prisma.student.deleteMany({
  where: { grade: 10 }
});
console.log(deletedCount);
text
{ count: 2 }

No where at All Is Dangerous Here Too

Exactly like raw SQL (Module 2, Lesson 1), calling updateMany({ data: { ... } }) or deleteMany() with no where at all affects every single row in the table. The same caution applies, always double-check the filter before running one.

Try It

  1. Create a new student with create, and confirm the full row, including id, comes back.
  2. Update that student’s grade with update, using their id in where.
  3. Call updateMany with a where that matches several rows, and confirm the response is { count: N }, not the actual rows.
  4. Call delete with an id that doesn’t exist, and read the error it throws. Compare this to what raw SQL’s DELETE does in the same situation (Module 2).

Recap

  • create, update, and delete each operate on exactly one row, update and delete require a unique where, and throw if no row matches.
  • updateMany and deleteMany affect any number of matching rows, returning only a count, never the actual rows.
  • Skipping where on a bulk operation is exactly as dangerous here as it is in raw SQL.

Next lesson: sorting and paginating query results.