Prisma CRUD examples
Topics
NextjsPrisma
Published on
21 Jan 2025
Prisma makes CRUD in Next.js simple, type-safe, and scalable. Define your schema, generate the client, and use Prisma’s API in your routes or server actions for all database operations.
prisma/schema.prisma
1generator client {
2 provider = "prisma-client-js"
3 output = "../lib/generated/prisma"
4}
5
6datasource db {
7 provider = "postgresql"
8 url = env("DATABASE_URL")
9 directUrl = env("DIRECT_URL")
10}
11
12enum Role {
13 USER
14 ADMIN
15}
16
17model User {
18 id String @id @default(auto()) @map("_id") @db.ObjectId
19 email String @unique
20 name String?
21 role Role @default(USER)
22 profileViews Int @default(0)
23 coinflips Boolean[]
24 posts Post[]
25 profile ExtendedProfile?
26}
27
28model Post {
29 id String @id @default(auto()) @map("_id") @db.ObjectId
30 title String
31 content String?
32 published Boolean @default(false)
33 author User @relation(fields: [authorId], references: [id])
34 authorId String @db.ObjectId
35}
36
37model ExtendedProfile {
38 id String @id @default(auto()) @map("_id") @db.ObjectId
39 bio String?
40 user User @relation(fields: [userId], references: [id])
41 userId String @unique @db.ObjectId
42}
Main CRUD Operations
1// Create
2const newUser = await prisma.user.create({
3 data: {
4 email: "test@example.com",
5 name: "Test User"
6 }
7});
8
9// Read
10// Find all users
11const allUsers = await prisma.user.findMany();
12
13// Find users with at least 100 profile views who've flipped "true"
14const activeUsers = await prisma.user.findMany({
15 where: {
16 profileViews: { gte: 100 },
17 coinflips: { has: true } // Checks array contains true
18 }
19});
20
21// Find a unique user
22const existingUser = await prisma.user.findUnique({
23 where: { email: "test@example.com" }
24});
25
26// Update
27const updatedUser = await prisma.user.update({
28 where: { id: newUser.id },
29 data: { name: "Updated Name" }
30});
31
32// Upsert (Create or Update)
33const upsertedUser = await prisma.user.upsert({
34 where: { email: "test@example.com" },
35 create: {
36 email: "test@example.com",
37 name: "New User"
38 },
39 update: {
40 profileViews: 10
41 }
42});
43
44// Delete with related posts
45const deletePosts = prisma.post.deleteMany({
46 where: { authorId: newUser.id }
47});
48
49const deleteUser = prisma.user.delete({
50 where: { id: newUser.id }
51});
52
53await prisma.$transaction([deletePosts, deleteUser]);
await prisma.$transaction([deletePosts, deleteUser])
executes multiple database operations as a single atomic transaction using Prisma.
- Atomic Execution:
All operations in the array either succeed together or fail together. If any operation fails, the entire transaction is rolled back, leaving the database in its original state. - Order Matters:
Operations run sequentially in the order they appear in the array. For example:
1// Delete posts first, THEN delete the user
2await prisma.$transaction([deletePosts, deleteUser]);
If you reverse the order ([deleteUser, deletePosts]
), deleting the user first would cause foreign key errors in the posts table.
Query Order: Always delete dependent records (e.g., posts) before the parent record (e.g., user).
Table of Contents