Type-Safe Database Operations
Prisma generates TypeScript types directly from your schema. Every query is type-checked at compile time — if your schema changes, TypeScript catches mismatches immediately.
Create
// Create a post with relations
const post = await db.post.create({
data: {
title: 'Getting Started with Prisma',
slug: 'getting-started-with-prisma',
content: 'Prisma is amazing...',
author: {
connect: { id: userId },
},
category: {
connectOrCreate: {
where: { slug: 'tutorials' },
create: { name: 'Tutorials', slug: 'tutorials' },
},
},
tags: {
connectOrCreate: [
{ where: { name: 'prisma' }, create: { name: 'prisma' } },
{ where: { name: 'typescript' }, create: { name: 'typescript' } },
],
},
},
include: {
author: { select: { name: true, email: true } },
category: true,
tags: true,
},
});
Read
// Find with filters, ordering, and pagination
const posts = await db.post.findMany({
where: {
published: true,
category: { slug: 'tutorials' },
tags: { some: { name: 'typescript' } },
},
orderBy: { publishedAt: 'desc' },
skip: (page - 1) * perPage,
take: perPage,
include: {
author: { select: { id: true, name: true, image: true } },
category: true,
_count: { select: { comments: true } },
},
});
// Find one or throw
const post = await db.post.findUniqueOrThrow({
where: { slug },
include: {
author: true,
tags: true,
comments: {
include: { author: true },
orderBy: { createdAt: 'desc' },
},
},
});
Update
// Update with optimistic concurrency
const updatedPost = await db.post.update({
where: { id: postId },
data: {
title: newTitle,
content: newContent,
updatedAt: new Date(),
tags: {
set: [], // Clear existing tags
connectOrCreate: newTags.map(tag => ({
where: { name: tag },
create: { name: tag },
})),
},
},
});
Delete
// Soft delete pattern
const archived = await db.post.update({
where: { id: postId },
data: { published: false, deletedAt: new Date() },
});
// Hard delete (cascades to comments via schema onDelete: Cascade)
await db.post.delete({ where: { id: postId } });
Aggregations
const stats = await db.post.aggregate({
where: { authorId: userId },
_count: { id: true },
_avg: { viewCount: true },
});
const postsByCategory = await db.category.findMany({
include: {
_count: { select: { posts: true } },
},
orderBy: { posts: { _count: 'desc' } },
});
Prisma's type safety means you get autocomplete for every field and relation, and TypeScript errors catch invalid queries before they reach production.