Prisma 是 Node.js/TypeScript 生态最流行的 ORM。 Claude Code 能生成完整的 Prisma Schema、Migration、 查询代码,让数据库开发效率翻倍。
为什么选 Prisma + Claude Code?
Prisma 的学习曲线难点:
Schema 语法(@relation 复杂关系)
Migration 策略(不破坏生产数据)
查询 API(include/select/where 嵌套)
事务处理
性能优化(N+1 问题)
Claude Code 能帮你搞定所有这些
场景一:从需求直接生成 Prisma Schema
Prompt:
帮我设计一个电商系统的 Prisma Schema,需求:
- 用户(User)可以有多个地址(Address)
- 商品(Product)属于某个分类,支持多个标签
- 订单(Order)包含多个订单项(OrderItem)
- 订单项关联商品,记录下单时的价格(快照)
- 支持软删除(deletedAt 字段)
- 使用 PostgreSQL
要求包含:
- 完整的字段类型和约束
- 关系定义(@relation)
- 数据库索引(@@index)
- 枚举类型(订单状态)
Claude Code 生成示例(关键部分):
prisma
generator client {
provider = "prisma-client-js"
}
datasource db {
provider = "postgresql"
url = env("DATABASE_URL")
}
enum OrderStatus {
PENDING
PAID
SHIPPED
DELIVERED
CANCELLED
}
model User {
id String @id @default(cuid())
email String @unique
name String
addresses Address[]
orders Order[]
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
deletedAt DateTime?
@@index([email])
}
model Product {
id String @id @default(cuid())
name String
price Decimal @db.Decimal(10, 2)
stock Int @default(0)
category Category @relation(fields: [categoryId], references: [id])
categoryId String
tags Tag[]
orderItems OrderItem[]
deletedAt DateTime?
@@index([categoryId])
}
model Order {
id String @id @default(cuid())
user User @relation(fields: [userId], references: [id])
userId String
status OrderStatus @default(PENDING)
totalPrice Decimal @db.Decimal(10, 2)
items OrderItem[]
createdAt DateTime @default(now())
@@index([userId, status])
}
model OrderItem {
id String @id @default(cuid())
order Order @relation(fields: [orderId], references: [id])
orderId String
product Product @relation(fields: [productId], references: [id])
productId String
quantity Int
unitPrice Decimal @db.Decimal(10, 2) // 下单时价格快照
}场景二:复杂查询生成
Prompt:
用 Prisma 写一个查询:
获取某用户的所有订单,
包含订单项(含商品名称和分类),
按创建时间倒序,
只返回 PAID 和 DELIVERED 状态的,
支持分页(cursor-based pagination)
Claude Code 生成:
typescript
async function getUserOrders(userId: string, cursor?: string, limit = 10) {
return prisma.order.findMany({
where: {
userId,
status: { in: ['PAID', 'DELIVERED'] }
},
include: {
items: {
include: {
product: {
select: {
name: true,
category: { select: { name: true } }
}
}
}
}
},
orderBy: { createdAt: 'desc' },
take: limit,
skip: cursor ? 1 : 0,
cursor: cursor ? { id: cursor } : undefined
})
}场景三:事务处理
Prompt:
写一个创建订单的 Prisma 事务:
1. 检查商品库存(不足则报错)
2. 扣减库存
3. 创建订单和订单项
4. 记录库存变动日志
以上操作必须原子执行,任何步骤失败则全部回滚
Claude Code 生成:
typescript
async function createOrder(userId: string, items: CartItem[]) {
return prisma.$transaction(async (tx) => {
// 1. 检查并锁定库存(SELECT FOR UPDATE)
for (const item of items) {
const product = await tx.product.findUniqueOrThrow({
where: { id: item.productId }
})
if (product.stock < item.quantity) {
throw new Error(`商品 ${product.name} 库存不足`)
}
}
// 2. 扣减库存
await Promise.all(items.map(item =>
tx.product.update({
where: { id: item.productId },
data: { stock: { decrement: item.quantity } }
})
))
// 3. 创建订单
const totalPrice = items.reduce((s, i) => s + i.price * i.quantity, 0)
return tx.order.create({
data: {
userId,
totalPrice,
items: { create: items.map(i => ({ ...i })) }
}
})
})
}场景四:Migration 策略
Prompt:
我需要给 User 表加一个 phoneNumber 字段(唯一索引),
但生产数据库里已有 10 万条数据(现有数据 phoneNumber 为空)。
帮我写一个安全的 Prisma Migration 方案,
不能让应用停机,不能丢失数据。
Claude Code 给出分步方案(先加 nullable,再填数据,再加约束)。
N+1 问题排查 Prompt
这段 Prisma 代码有 N+1 查询问题,帮我优化:
const orders = await prisma.order.findMany()
const result = await Promise.all(
orders.map(async o => ({
...o,
user: await prisma.user.findUnique({ where: { id: o.userId } })
}))
)
来源:Anthropic Claude Code 官方文档 - docs.anthropic.com/en/docs/claude-code