Working with Delete Operations
1. Deleting Single Record
await prisma.user.delete({ where: { id: 1 } });
| Aspect | Detail |
| Where | Unique field |
| Error | P2025 if missing |
2. Deleting Multiple Records
const res = await prisma.session.deleteMany({
where: { expiresAt: { lt: new Date() } }
});
| Aspect | Detail |
| Returns | Count of removed rows |
| Cascades | Respect referential actions |
3. Using Where Clause Filters
| Variant | Filter |
delete | Unique |
deleteMany | Arbitrary |
4. Handling Cascade Deletes
| Action | Effect |
| Cascade | Children removed automatically |
| Restrict | Throws P2003 if dependents exist |
| Manual | Wrap deletes in $transaction |
5. Implementing Soft Delete Pattern
await prisma.user.update({
where: { id: 1 },
data: { deletedAt: new Date() }
});
| Component | Use |
| Schema | deletedAt DateTime? |
| Read filter | Always add deletedAt: null |
| Extension | Apply via $extends for DRY |
6. Understanding Hard vs Soft Delete
Hard Delete
- Frees storage
- Irrecoverable
- Cascades easily
- Best for ephemeral data
Soft Delete
- Audit-friendly
- Reversible
- Requires query filters
- Best for user/business data
| Aspect | Hard | Soft |
| Storage | Reclaimed | Grows |
| Recovery | None | Yes |
await prisma.user.update({
where: { id: 1 },
data: { posts: { deleteMany: { published: false } } }
});
| Nested Op | Use |
delete | Specific row |
deleteMany | Filtered subset |
8. Handling Delete Errors
| Code | Cause |
P2025 | Record not found |
P2003 | FK constraint blocks delete |
P2014 | Required relation violation |
9. Validating Before Delete
| Check | Strategy |
| Ownership | Filter by userId in where |
| Existence | Use deleteMany for idempotent ops |
| Permissions | Authorize before issuing query |
10. Restoring Soft Deleted Records
await prisma.user.update({
where: { id: 1 },
data: { deletedAt: null }
});
| Step | Detail |
| Reset flag | Set deletedAt to null |
| Restore relations | Cascade restore if business requires |