Prisma 完整指南

prisma

#resource / typescript #type / moc #status / growing

Prisma 完整指南

Overview

object-relational-mapping-orm

什么是 Prisma?

Prisma 是一个现代化的数据库工具包(Node.js/TypeScript ORM 工具),包含以下三个主要工具:

  1. Prisma Client - 类型安全的数据库客户端
  2. Prisma Migrate - 数据库迁移工具
  3. Prisma Studio - 现代化的数据库 GUI

核心文件

  • schema.prisma - 数据库模式定义文件
  • prisma/migrations/ - 数据库迁移文件
  • node_modules/.prisma/client/ - 生成的客户端代码

数据建模

// 数据源配置
datasource db {
  provider = "postgresql"
  url      = env("DATABASE_URL")
}

// 生成器配置
generator client {
  provider = "prisma-client-js"
}

// 模型定义
model User {
  id        Int      @id @default(autoincrement())
  email     String   @unique
  name      String?
  posts     Post[]
  createdAt DateTime @default(now())

  @@map("users")
}

model Post {
  id        Int      @id @default(autoincrement())
  title     String
  content   String?
  published Boolean  @default(false)
  authorId  Int
  author    User     @relation(fields: [authorId], references: [id])

  @@map("posts")
}

🚀 使用指南

prisma-getting-started-official-demo

安装和初始化

# 安装 Prisma CLI
npm install prisma --save-dev
npm install @prisma/client

# 初始化 Prisma
npx prisma init

# 生成客户端
npx prisma generate

数据库连接

// 1. 导入 Prisma Client
import { PrismaClient } from '@prisma/client'

// 2. 创建实例
const prisma = new PrismaClient()

// 3. 使用(推荐:全局单例模式)
export const prisma = new PrismaClient({
  log: ['query', 'info', 'warn', 'error'],
})

基础 CRUD 操作

// 创建
const user = await prisma.user.create({
  data: {
    email: 'alice@example.com',
    name: 'Alice',
  },
})

// 查询
const users = await prisma.user.findMany({
  where: {
    email: {
      contains: '@example.com',
    },
  },
  include: {
    posts: true,
  },
})

// 更新
const updatedUser = await prisma.user.update({
  where: { id: 1 },
  data: { name: 'Alice Smith' },
})

// 删除
await prisma.user.delete({
  where: { id: 1 },
})

高级查询

// 条件查询
const users = await prisma.user.findMany({
  where: {
    AND: [
      { name: { startsWith: 'A' } },
      { posts: { some: { published: true } } },
    ],
  },
})

// 分页
const users = await prisma.user.findMany({
  skip: 10,
  take: 10,
  orderBy: { createdAt: 'desc' },
})

// 聚合查询
const userCount = await prisma.user.count()
const postStats = await prisma.post.aggregate({
  _count: { id: true },
  _avg: { id: true },
  where: { published: true },
})

关系查询

// 一对多关系
const userWithPosts = await prisma.user.findUnique({
  where: { id: 1 },
  include: {
    posts: {
      where: { published: true },
      orderBy: { createdAt: 'desc' },
    },
  },
})

// 多对多关系
const postWithCategories = await prisma.post.findUnique({
  where: { id: 1 },
  include: {
    categories: true,
  },
})

// 嵌套写入
const userWithPosts = await prisma.user.create({
  data: {
    email: 'alice@example.com',
    posts: {
      create: [
        { title: 'My first post' },
        { title: 'My second post' },
      ],
    },
  },
  include: {
    posts: true,
  },
})

事务处理

// 基础事务
await prisma.$transaction(async (tx) => {
  const user = await tx.user.create({
    data: { email: 'alice@example.com' },
  })

  const post = await tx.post.create({
    data: {
      title: 'My post',
      authorId: user.id,
    },
  })

  return { user, post }
})

// 交互式事务
await prisma.$transaction(async (tx) => {
  // 复杂的业务逻辑
  const result = await someComplexOperation(tx)
  return result
})

🛠️ 常用命令表格

命令描述常用选项
prisma init初始化 Prisma 项目--datasource-provider
prisma generate生成 Prisma Client--schema
prisma db push推送 schema 到数据库--force-reset, --accept-data-loss
prisma migrate dev开发环境迁移--name, --create-only
prisma migrate deploy生产环境应用迁移-
prisma migrate reset重置数据库并重新应用迁移--force
prisma migrate status查看迁移状态-
prisma studio启动 Prisma Studio--port, --browser
prisma db seed运行种子数据-
prisma db pull从数据库拉取 schema--force
prisma format格式化 schema 文件-
prisma validate验证 schema 文件-
prisma version查看版本信息-

🏆 实战经验

最佳实践

1. 客户端实例管理

// ❌ 错误:每次都创建新实例
export async function getUsers() {
  const prisma = new PrismaClient()
  return await prisma.user.findMany()
}

// ✅ 正确:使用全局单例
const globalForPrisma = globalThis as unknown as {
  prisma: PrismaClient | undefined
}

export const prisma = globalForPrisma.prisma ?? new PrismaClient()

if (process.env.NODE_ENV !== 'production') globalForPrisma.prisma = prisma

2. 错误处理

try {
  const user = await prisma.user.create({
    data: { email: 'existing@example.com' },
  })
} catch (error) {
  if (error instanceof Prisma.PrismaClientKnownRequestError) {
    if (error.code === 'P2002') {
      console.log('邮箱已存在')
    }
  }
  throw error
}

3. 类型安全

// 使用生成的类型
type UserWithPosts = Prisma.UserGetPayload<{
  include: { posts: true }
}>

// 自定义查询类型
const userQuery = prisma.user.findUnique({
  where: { id: 1 },
  include: { posts: true },
}).then(user => user as UserWithPosts)

4. 性能优化

// 选择性查询字段
const users = await prisma.user.findMany({
  select: {
    id: true,
    email: true,
    // 不选择 password 等敏感字段
  },
})

// 使用索引
model User {
  id        Int      @id @default(autoincrement())
  email     String   @unique  // 自动创建索引
  name      String?
  createdAt DateTime @default(now())

  @@index([createdAt])  // 手动创建索引
  @@map("users")
}

常见问题解决

连接问题

# 检查数据库连接
npx prisma db push --preview-feature

# 查看连接字符串
echo $DATABASE_URL

迁移冲突

# 查看迁移状态
npx prisma migrate status

# 解决冲突
npx prisma migrate resolve --applied 20240101120000_migration_name

# 强制重置(开发环境)
npx prisma migrate reset --force

类型生成问题

# 清理并重新生成
rm -rf node_modules/.prisma
npx prisma generate

# 检查 schema 语法
npx prisma validate

📝 经验总结

数据库重置

reset-database-with-prisma

开发环境配置

// .env
DATABASE_URL="postgresql://user:password@localhost:5432/dbname?schema=public"

// prisma/schema.prisma
datasource db {
  provider = "postgresql"
  url      = env("DATABASE_URL")
}

generator client {
  provider = "prisma-client-js"
  previewFeatures = ["postgresqlExtensions"]
}

生产环境部署

// 生产环境配置
const prisma = new PrismaClient({
  log: process.env.NODE_ENV === 'development' ? ['query', 'error', 'warn'] : ['error'],
  errorFormat: 'minimal',
})

数据库设计原则

  1. 使用合适的数据类型

    • String 用于文本
    • Int 用于整数
    • Float 用于小数
    • Boolean 用于布尔值
    • DateTime 用于时间戳
    • Json 用于复杂对象
  2. 合理使用索引

    • 外键字段自动创建索引
    • 常用查询字段添加索引
    • 避免过度索引
  3. 规范化 vs 反规范化

    • 优先考虑规范化设计
    • 性能关键场景可适当反规范化
    • 使用视图或计算字段

迁移策略

# 开发环境:快速迭代
npx prisma migrate dev --name "add-user-profile"

# 生产环境:安全部署
npx prisma migrate deploy

# 数据迁移:使用脚本
npx prisma db execute --file ./migrations/data-migration.sql

prisma-cheatsheet

📖 信息参考

官方资源

学习资源

社区资源

相关工具

  • Prisma Studio - 数据库 GUI
  • Prisma Client Extensions - 客户端扩展
  • Prisma Accelerate - 查询加速
  • Prisma Pulse - 实时数据库订阅

版本兼容性

Prisma 版本Node.js数据库支持
5.x16+PostgreSQL, MySQL, SQLite, SQL Server, MongoDB
4.x14+PostgreSQL, MySQL, SQLite, SQL Server, MongoDB
3.x12+PostgreSQL, MySQL, SQLite

故障排除

# 查看详细日志
DEBUG="prisma:*" npx prisma db push

# 检查数据库连接
npx prisma db execute --file <(echo "SELECT 1")

# 重置客户端缓存
rm -rf node_modules/.prisma && npm install
创建于 2025/1/1 更新于 2026/5/27