| name | prisma-orm |
| description | Prisma ORM schema design, migrations, relations, query optimization, and database integration patterns. |
| allowed-tools | Read, Write, Edit, Bash, Glob, Grep |
| graph | {"domains":["domain:web-development"],"specializations":["specialization:web-development"],"skillAreas":["skill-area:object-relational-mapping","skill-area:backend-data-persistence"],"roles":["role:backend-engineer","role:fullstack-engineer"],"topics":["topic:data-mapper"]} |
Prisma ORM Skill
Expert assistance for Prisma ORM schema design, migrations, relations, query optimization, and database integration patterns.
Capabilities
- Design Prisma schemas with proper relations
- Generate and manage database migrations
- Optimize queries for performance
- Implement type-safe database access
- Configure multi-database support
- Set up seeding and testing strategies
Usage
Invoke this skill when you need to:
- Design database schemas with Prisma
- Set up migrations and database workflows
- Optimize database queries
- Implement complex relations
- Configure Prisma with Next.js or other frameworks
Inputs
| Parameter | Type | Required | Description |
|---|
| database | string | No | postgresql, mysql, sqlite, mongodb |
| models | array | No | List of models to create |
| relations | array | No | Model relationships |
| features | array | No | migrations, seeding, edge |
Schema Configuration
{
"database": "postgresql",
"models": [
{
"name": "User",
"fields": [
{ "name": "email", "type": "String", "unique": true },
{ "name": "name", "type": "String", "optional": true },
{ "name": "posts", "type": "Post", "relation": "one-to-many" }
Output Structure
project/
โโโ prisma/
โ โโโ schema.prisma # Database schema
โ โโโ migrations/ # Migration files
โ โ โโโ 20240101_init/
โ โ โโโ migration.sql
โ โโโ seed.ts # Seed script
โโโ lib/
โ โโโ db/
โ โโโ prisma.ts # Prisma client singleton
โ โโโ queries/
โ โ โโโ users.ts # User queries
โ โ โโโ posts.ts # Post queries
โ โโโ types.ts # Extended types
โโโ package.json
Generated Code Patterns
Prisma Schema
// prisma/schema.prisma
generator client {
provider = "prisma-client-js"
previewFeatures = ["driverAdapters"]
}
datasource db {
provider = "postgresql"
url = env("DATABASE_URL")
}
model User {
id String @id @default(cuid())
email String @unique
name String?
password String
role Role @default(USER)
posts Post[]
comments Comment[]
profile Profile?
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
@@index([email])
@@map("users")
}
model Profile {
id String @id @default(cuid())
bio String?
avatar String?
userId String @unique
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
@@map("profiles")
}
model Post {
id String @id @default(cuid())
title String
slug String @unique
content String?
published Boolean @default(false)
authorId String
author User @relation(fields: [authorId], references: [id], onDelete: Cascade)
categories Category[]
comments Comment[]
tags Tag[]
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
@@index([authorId])
@@index([slug])
@@map("posts")
}
model Category {
id String @id @default(cuid())
name String @unique
posts Post[]
@@map("categories")
}
model Tag {
id String @id @default(cuid())
name String @unique
posts Post[]
@@map("tags")
}
model Comment {
id String @id @default(cuid())
content String
postId String
post Post @relation(fields: [postId], references: [id], onDelete: Cascade)
authorId String
author User @relation(fields: [authorId], references: [id], onDelete: Cascade)
parentId String?
parent Comment? @relation("CommentReplies", fields: [parentId], references: [id])
replies Comment[] @relation("CommentReplies")
createdAt DateTime @default(now())
@@index([postId])
@@index([authorId])
@@map("comments")
}
enum Role {
USER
ADMIN
MODERATOR
}
Prisma Client Singleton
import { PrismaClient } from '@prisma/client';
const globalForPrisma = globalThis as unknown as {
prisma: PrismaClient | undefined;
};
export const prisma =
globalForPrisma.prisma ??
new PrismaClient({
log:
process.env.NODE_ENV === 'development'
? ['query', 'error', 'warn']
: ['error'],
});
if (process.env.NODE_ENV !== 'production') globalForPrisma.prisma = prisma;
export default prisma;
Query Functions
import { prisma } from '../prisma';
import { Prisma } from '@prisma/client';
export type UserWithPosts = Prisma.UserGetPayload<{
include: { posts: true; profile: true };
}>;
export async function getUserById(id: string): Promise<UserWithPosts | null> {
return prisma.user.findUnique({
where: { id },
include: {
posts: {
where: { published: true },
orderBy: { createdAt: 'desc' },
take: 10,
},
profile: true,
},
});
}
export async function getUserByEmail(email: string) {
return prisma.user.findUnique({
: { email },
: {
: ,
: ,
: ,
: ,
},
});
}
() {
prisma..({
data,
: {
: ,
},
});
}
() {
prisma..({
: { id },
data,
});
}
() {
prisma..({
: { id },
});
}
() {
{ skip = , take = , where, orderBy = { : } } = params;
[users, total] = prisma.$transaction([
prisma..({
skip,
take,
where,
orderBy,
: {
: ,
: ,
: ,
: ,
: ,
: {
: { : },
},
},
}),
prisma..({ where }),
]);
{
users,
total,
: .(total / take),
};
}
Post Queries with Relations
import { prisma } from '../prisma';
import { Prisma } from '@prisma/client';
export async function getPublishedPosts(params: {
page?: number;
limit?: number;
categoryId?: string;
authorId?: string;
search?: string;
}) {
const { page = 1, limit = 10, categoryId, authorId, search } = params;
const skip = (page - 1) * limit;
const where: Prisma.PostWhereInput = {
published: true,
...(categoryId && {
categories: { some: { id: categoryId } },
}),
...(authorId && { authorId }),
...(search && {
OR: [
{ title: { contains: search, mode: 'insensitive' } },
{ content: { contains: search, mode: 'insensitive' } },
],
}),
};
const [posts, total] = await prisma.$transaction([
prisma.post.findMany({
where,
skip,
take: limit,
orderBy: { createdAt: },
: {
: {
: { : , : , : },
},
: ,
: ,
: {
: { : },
},
},
}),
prisma..({ where }),
]);
{
posts,
: {
page,
limit,
total,
: .(total / limit),
},
};
}
() {
prisma..({
: { slug },
: {
: {
: { : , : , : },
},
: ,
: ,
: {
: { : },
: {
: { : { : , : } },
: {
: {
: { : { : , : } },
},
},
},
: { : },
},
},
});
}
() {
{ title, content, authorId, categoryIds = [], tagNames = [] } = data;
slug = title
.()
.(, )
.(, );
prisma..({
: {
title,
slug,
content,
authorId,
: {
: categoryIds.( ({ id })),
},
: {
: tagNames.( ({
: { name },
: { name },
})),
},
},
: {
: ,
: ,
: ,
},
});
}
Seed Script
import { PrismaClient } from '@prisma/client';
import { hash } from 'bcryptjs';
const prisma = new PrismaClient();
async function main() {
console.log('Seeding database...');
const categories = await Promise.all([
prisma.category.upsert({
where: { name: 'Technology' },
update: {},
create: { name: 'Technology' },
}),
prisma.category.upsert({
where: { name: 'Design' },
update: {},
create: { name: 'Design' },
}),
]);
const adminPassword = await hash('admin123', 12);
const admin = await prisma.user.upsert({
where: { : },
: {},
: {
: ,
: ,
: adminPassword,
: ,
: {
: {
: ,
},
},
},
});
prisma..({
: [
{
: ,
: ,
: ,
: ,
: admin.,
},
{
: ,
: ,
: ,
: ,
: admin.,
},
],
: ,
});
.();
}
()
.( {
.(e);
process.();
})
.( () => {
prisma.$disconnect();
});
Migration Workflow
npx prisma migrate dev --name init
npx prisma migrate deploy
npx prisma migrate reset
npx prisma generate
npx prisma db seed
Package.json Scripts
{
"scripts": {
"db:generate": "prisma generate",
"db:push": "prisma db push",
"db:migrate": "prisma migrate dev",
"db:migrate:deploy": "prisma migrate deploy",
"db:seed": "prisma db seed",
"db:studio": "prisma studio",
"db:reset": "prisma migrate reset"
},
"prisma": {
"seed": "tsx prisma/seed.ts"
}
}
Query Optimization Patterns
Select Only Needed Fields
const user = await prisma.user.findUnique({ where: { id } });
const user = await prisma.user.findUnique({
where: { id },
select: {
id: true,
name: true,
email: true,
},
});
Batch Operations
const [user, posts] = await prisma.$transaction([
prisma.user.create({ data: userData }),
prisma.post.createMany({ data: postsData }),
]);
await prisma.$transaction(async (tx) => {
const user = await tx.user.create({ data: userData });
await tx.post.create({
data: { ...postData, authorId: user.id },
});
});
Pagination with Cursor
async function getPaginatedPosts(cursor?: string) {
return prisma.post.findMany({
take: 10,
...(cursor && {
skip: 1,
cursor: { id: cursor },
}),
orderBy: { createdAt: 'desc' },
});
}
Dependencies
{
"dependencies": {
"@prisma/client": "^6.0.0"
},
"devDependencies": {
"prisma": "^6.0.0"
}
}
Workflow
- Define schema - Create models and relations
- Generate client - Run prisma generate
- Create migrations - Run prisma migrate dev
- Implement queries - Type-safe database access
- Seed database - Create initial data
- Optimize queries - Select, batch, index
Best Practices Applied
- Type-safe queries with Prisma Client
- Proper relation modeling
- Efficient pagination patterns
- Transaction support
- Cascade deletes where appropriate
- Indexed frequently queried fields
References
Target Processes
- database-schema-design
- migration-management
- query-optimization
- data-seeding
- database-testing