Nestjs框架: 由权限模型设计到 Prisma 数据库迁移的演示

好的,接下来我将根据你提供的内容,整理出一个结构清晰、逻辑严谨、信息量大的项目实操指导文档,用于指导你完成 RDAC权限系统中的数据库建模与迁移管理实践,包括:

  1. 数据库结构补充:角色、用户角色关系建模
  2. Prisma Migrate 生命周期管理命令详解
  3. 数据库迁移脚本的创建与管理
  4. 生产与开发数据库同步策略
  5. 多迁移版本控制与冲突解决机制

数据库添加User模型


基于Prisma设计User模型


generator client {
  provider = "prisma-client-js"
  output   = "./clients/postgresql"
}

datasource db {
  provider = "postgresql"
  url      = env("DATABASE_URL")
}

model User {
  id       Int        @id @default(autoincrement())
  username String     @unique
  password String
  // userRole UserRole[] // 后面添加Role模型的时候,要把这个打开

  @@map("users")
}

以上是一开始的User模型,我们先把这个模型同步到远程,此时远程没有 testdb 数据库

我们现在执行 $ $ npx prisma migrate dev --name init

  • --name init:定义本次迁移的名称,便于后续追踪
  • 执行该命令后,Prisma 会:
    • 删除当前数据库(开发环境允许)
    • 重新创建数据库结构
    • 创建初始的迁移文件(migration.sql
  • 若不想确认删除数据,可添加 --force 参数

输出如下

Environment variables loaded from .env
Prisma schema loaded from prisma/schema.prisma
Datasource "db": PostgreSQL database "testdb", schema "public" at "localhost:15432"

PostgreSQL database testdb created at localhost:15432

Applying migration `20250813093251_init`

The following migration(s) have been created and applied from new schema changes:

prisma/migrations/
  └─ 20250813093251_init/
    └─ migration.sql

Your database is now in sync with your schema.

✔ Generated Prisma Client (v6.12.0) to ./prisma/clients/postgresql in 168ms

查看数据库是否同步

在这里插入图片描述
可以看到,数据库同步了,注意,也可以生成迁移脚本但不应用到数据库

npx prisma migrate dev --name role --create-only
  • 仅生成 SQL 脚本,不执行数据库操作
  • 适用于预览或审查脚本内容后再决定是否执行

下面我们继续补充数据库模型

数据库结构补充:角色模型设计


1 )添加 Role 和 UserRole 模型

model Role {
  id          Int        @id @default(autoincrement())
  name        String     @unique // 角色名称(如:admin、editor) 
  description String? // 角色描述 
  createdAt   DateTime   @default(now())
  updatedAt   DateTime   @updatedAt
  users       UserRole[] // 关联用户(多对多) 

  // permissions RolePermission[]  // 关联权限(多对多)这个暂时用不到 
  @@map("roles")
}

model UserRole {
  userId Int
  roleId Int
  user   User @relation(fields: [userId], references: [id], onDelete: Cascade)
  role   Role @relation(fields: [roleId], references: [id], onDelete: Cascade)

  @@id([userId, roleId]) // 联合主键 
  @@map("user_roles") // 数据库表名 
}

关于 Role

  • id:角色的唯一标识符
  • name:角色名称,唯一性保证
  • description:角色描述,可选字段
  • users:与用户角色之间的关系

关于 UserRole

  • 联合主键(userId, roleId)用于保证一个用户只能拥有一个角色
  • 使用 @@map 指定数据库表名,便于后续维护
  • 该模型用于连接用户与角色之间的映射关系

2 ) 解开 User 模型中的注释

model User {
  userRole UserRole[] // 这里之前的注释打开
}

3 ) 之后,我们继续执行迁移

现在执行 $ $ npx prisma migrate dev --name role

Environment variables loaded from .env
Prisma schema loaded from prisma/schema.prisma
Datasource "db": PostgreSQL database "testdb", schema "public" at "localhost:15432"

Applying migration `20250813101143_role`

The following migration(s) have been created and applied from new schema changes:

prisma/migrations/
  └─ 20250813101143_role/
    └─ migration.sql

Your database is now in sync with your schema.

✔ Generated Prisma Client (v6.12.0) to ./prisma/clients/postgresql in 543ms

这时候,我们的 src/prisma/migrations 中有了2次迁移记录

刷新远程数据库,查看已经同步了

在这里插入图片描述

4 ) 我们查看总共的迁移记录如下

执行 $ npx prisma migrate status

Environment variables loaded from .env
Prisma schema loaded from prisma/schema.prisma
Datasource "db": PostgreSQL database "testdb", schema "public" at "localhost:15432"

2 migrations found in prisma/migrations

Database schema is up to date!

注意,这个命令会

  1. 查看当前所有未应用的迁移
  2. 适用于生产环境前的检查

Prisma Migrate 其他管理命令详解


1 ) 应用所有迁移到数据库

npx prisma migrate deploy
  • 适用于生产环境部署
  • 自动执行所有未应用的迁移
  • 自动按时间戳顺序执行 migrations 目录中的所有 SQL
  • 若数据库不存在会自动创建

2 ) 数据重置(开发环境专用)

需清空数据库并重新应用所有迁移(生产环境禁止使用):

npx prisma migrate reset
  • 作用:删除所有表 → 重新创建数据库 → 应用所有迁移脚本 → 执行 seed 脚本(若有)
  • 如果没有数据库,它会自动创建数据库

3 ) 回滚某次迁移

npx prisma migrate resolve --rolled-back "20250813101143_role"

适用场景

  • 迁移执行失败后修复:当迁移因语法错误、依赖问题等失败时,可先标记为回滚,修正迁移文件后重新执行 $ npx prisma migrate dev
  • 临时调整迁移顺序:在开发环境中需跳过某次迁移直接应用后续版本时,可通过标记回滚实现状态修正
  • 该命令仅修改状态标记,不会删除或恢复数据库中的数据/表结构
  • 若需实际回滚数据,需手动编写逆向SQL或使用备份恢复。

完整操作示例

  • 场景背景: 假设在开发环境中,迁移20250813101143_role因字段类型错误执行失败,需修复后重新应用
  • 标记迁移为已回滚
    • $ npx prisma migrate resolve --rolled-back "20250813101143_role"
  • 修正迁移文件
    • 编辑prisma/migrations/20250813101143_role/migration.sql ,修正字段定义错误(如将重复字段名改为user_role)
  • 重新应用迁移
    • $ npx prisma migrate dev --name fixed_role_migration
  • 此时Prisma会基于修正后的文件生成新迁移,并更新状态记录

步骤详解
查看失败信息
执行npx prisma migrate dev时提示错误:

Error: column “role” of relation “users” already exists

4 ) 手动标记某次迁移为“已应用”

npx prisma migrate resolve --applied "20250813101143_role"
  • 用于解决迁移冲突问题,尤其是数据库结构已变更但未通过 Prisma 管理的情况

场景一:数据库结构手动变更后与Prisma迁移状态同步
当数据库已通过外部工具(如SQL客户端)手动执行了表结构修改(例如添加字段、创建索引),而Prisma迁移记录未更新时,可使用migrate resolve --applied命令将对应迁移标记为已应用,避免重复执行迁移或冲突。

  • 操作示例:
    假设手动为用户表添加了role字段,且已创建Prisma迁移文件20250813101143_role(内含添加role字段的SQL),但数据库变更已通过外部工具完成,无需再次执行迁移:
    npx prisma migrate resolve --applied "20250813101143_role" 
    
  • 效果:
    Prisma会将该迁移记录标记为“已应用”,后续执行prisma migrate dev时不会重复处理此迁移

场景二:迁移冲突后的状态修复
若因分支合并或迁移文件修改导致迁移历史不一致(例如本地迁移与远程数据库状态冲突),可通过手动标记解决冲突。

  • 冲突情境:
    开发分支A创建了迁移20250813101143_role并已应用,开发分支B未同步该迁移却直接修改了数据库。合并分支后,Prisma检测到数据库状态与迁移记录不匹配。
  • 解决命令:
    npx prisma migrate resolve --applied "20250813101143_role" 
    
  • 关键说明:
    需确保数据库实际结构与迁移文件内容完全一致,否则可能导致数据不一致[1][2]。

场景三:跳过测试或冗余迁移
在测试环境中,若某迁移因重复执行或环境差异无需实际运行(如仅调整字段注释),可手动标记为已应用以跳过执行。

  • 示例流程:
    1. 创建空迁移(仅含描述性变更):
      npx prisma migrate dev --name "update_comment" --create-only 
      
    2. 手动修改数据库后标记迁移为已应用:
      npx prisma migrate resolve --applied "20250813152000_update_comment" 
      

注意事项与风险提示

注意点详细说明
数据一致性校验标记前务必通过prisma db pull或数据库客户端确认实际结构与迁移内容一致。
备份建议操作前备份数据库,避免误标记导致迁移历史混乱[1]。
生产环境谨慎使用生产环境优先通过正常迁移流程同步变更,手动标记仅作为紧急修复手段[3]。

通过上述示例可见,prisma migrate resolve --applied适用于手动对齐数据库状态与迁移记录的场景,但需严格确保操作前的状态一致性,避免引入隐性错误。

5 ) 对比数据库结构差异

npx prisma migrate diff --from-url "mysql://user:pass@localhost:3306/db1" --to-url "mysql://user:pass@remote:3306/db2"
  • 可用于:
    • 开发数据库与生产数据库的结构对比
    • 生成差异 SQL 语句或用于同步
  • 非常适合用于 CI/CD 流程中的数据库一致性验证

脚本自动化与 package.json 配置建议

为提升开发效率,建议在 package.json 中添加以下常用命令:

"scripts": {
  "migrate:dev": "npx prisma migrate dev",
  "migrate:reset": "npx prisma migrate reset",
  "migrate:deploy": "npx prisma migrate deploy",
  "migrate:status": "npx prisma migrate status",
  "db:push": "npx prisma db push",
  "generate": "npx prisma generate"
}

使用示例:

npm run migrate:dev --name role
npm run migrate:reset
npm run migrate:deploy

多版本迁移控制与冲突解决策略


1 ) 多迁移版本控制

  • 每次执行 migrate dev 会生成带时间戳的迁移文件
  • 所有迁移文件存放于 prisma/migrations 目录中
  • 支持选择性应用某些迁移,跳过部分迁移

2 ) 冲突解决流程

  1. 冲突场景:

    • 本地数据库结构与迁移记录不一致
    • 某次迁移执行失败,但记录已标记为成功
  2. 解决方式:

    • 使用 resolve 命令手动标记迁移状态。
    • 示例:
      npx prisma migrate resolve --applied "20250405123456_init"
      
  3. 注意事项:

    • 不建议在生产环境中频繁使用 migrate:reset
    • 建议在 CI/CD 中集成 migrate:statusmigrate:deploy,确保数据库结构一致性

总结与建议

功能模块推荐使用命令使用场景说明
初始化迁移migrate dev --name init首次创建数据库结构
新增迁移脚本migrate dev --name role添加角色模型
应用迁移到生产环境migrate deploy生产环境数据库结构同步
数据库结构对比migrate diff开发与生产数据库结构差异分析
手动解决迁移冲突migrate resolve --applied xxx迁移记录与数据库状态不一致时使用
数据库重置(开发)migrate reset开发过程中快速重置数据库

官方资源

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Wang's Blog

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值