首页 / Prisma ORM 入门教程 / 从其他 ORM 迁移到 Prisma

Prisma ORM 入门教程

从其他 ORM 迁移到 Prisma

本教程共 54 篇 · 第 51 篇 · 更新于 2026-08-11 · 约 5 分钟阅读

迁移DrizzleMongooseSequelizeTypeORM内省基线迁移schema-first

本节目标:掌握从任意 ORM 迁到 Prisma 的通用流程,看懂 schema-first 与 code-first 的本质区别,能判断自己的项目该不该迁移。

先理解两种建模哲学

如 §01 所述,Prisma 采用 schema-first(Schema 文件驱动)建模,与 code-first 路线的完整对比见第 01 章。这里只保留迁移视角的对比:

维度schema-first(Prisma)code-first(Drizzle/TypeORM)
模型定义schema.prisma 声明式文件TS 代码 / 装饰器类
类型来源生成器产出,全链路类型安全类型推断,查询结果才有类型
SQL 依赖不熟 SQL 也能干活接近 SQL,适合 SQL 高手
关系处理嵌套读取、嵌套写入、隐式多对多手动 join / relations 配置

两种路线没有绝对优劣:团队里 SQL 水平参差、看重协作和可维护性,选 schema-first;个人项目追求极致控制和最小开销,code-first 更顺手。迁移决策的前提是先想清楚这一点。

通用五步迁移流程

官方为每个 ORM 都准备了迁移指南,流程完全一致,共五步:

  1. 安装 Prisma CLI 与依赖
  2. 内省(Introspection)现有数据库
  3. 建立基线迁移(baseline)
  4. 安装并生成 Prisma Client
  5. 渐进替换查询,而非一次性重写

这套流程对 REST API、GraphQL API、任意应用形态都成立。

第一步到第三步:内省与基线

安装依赖(以 PostgreSQL 为例,其他数据库换对应驱动适配器):

npm install prisma @types/pg --save-dev
npm install @prisma/client @prisma/adapter-pg pg

初始化并连接现有数据库。Drizzle 与 Prisma 的连接字符串格式相同,已有的 DATABASE_URL 直接可用:

npx prisma init --output ../generated/prisma
npx prisma db pull

db pull 逆向数据库结构,生成模型定义。老库的表名、字段名会被原样搬进 Schema。想符合 Prisma 命名习惯(模型 PascalCase、字段 camelCase),用映射属性解耦,不改动数据库:

model Todo {
  id   Int     @id
  text String
  done Boolean @default(false)

  @@map("todo")
}
Note

在 v7 中,datasource 块只留 provider,连接字符串配置在 prisma.config.ts 里通过 env("DATABASE_URL") 提供。

然后建立基线迁移。库已经存在,不能用 migrate dev 从头建,要生成一份描述现状的 SQL 并标记为「已应用」:

mkdir -p prisma/migrations/0_init
npx prisma migrate diff --from-empty --to-schema prisma/schema.prisma --script > prisma/migrations/0_init/migration.sql
npx prisma migrate resolve --applied 0_init

从这之后,Prisma Migrate 就接管了 Schema 演进,以后改模型用 migrate dev 生成新迁移即可。

渐进替换查询

最后一步是替换代码。原则:先换读操作,再换写操作,一个模块一个模块来,Prisma 和其他 ORM 可以共存。以 Sequelize 为例的对照:

// Sequelize:查询
const users = await User.findAll({
  where: { active: true },
  limit: 10,
  order: [["createdAt", "DESC"]],
});

// Prisma:同样的查询
const users = await prisma.user.findMany({
  where: { active: true },
  take: 10,
  orderBy: { createdAt: "desc" },
});

创建带关联的记录,Prisma 的嵌套写入一步完成,其他 ORM 通常要两步:

// TypeORM:先建用户,再建文章
await connection.transaction(async (manager) => {
  const user = manager.create(User, { name: "Alice" });
  await manager.save(user);
  const post = manager.create(Post, { title: "Hello", author: user });
  await manager.save(post);
});

// Prisma:一个调用,自动事务
await prisma.user.create({
  data: {
    name: "Alice",
    posts: { create: { title: "Hello" } },
  },
});
Tip

换写操作时注意差异:Drizzle 可以「原地取反」布尔字段(not(todo.done)),Prisma 需要先 findUniqueupdateincludeselect 不能同层混用,要嵌套使用。

从 Mongoose 迁移:注意版本边界

Mongoose 是 MongoDB 的 ODM。迁移流程相同(内省 → 生成 → 替换),但有一个必须提前知道的边界:

Important

MongoDB 在 Prisma ORM v7 中尚不支持。官方建议 MongoDB 用户继续使用 Prisma ORM v6.19。本教程以 SQL 数据库为主线,MongoDB 相关迁移请留在 v6 路线执行。

另外 MongoDB 是「无 Schema」数据库,内省靠采样现有数据推断结构,所以迁移前要保证库里已有足够的数据样本。ObjectId 类型的引用关系需要手工整理成 @relation 关系字段,Mongoose 的 populate() 对应 Prisma 的 include

迁移决策建议

综合官方对比与社区观点,给三类项目一个判断框架:

  • 想迁移的:团队多人协作、类型安全诉求强、想统一迁移与查询工具链、现有 ORM 的关系处理让你反复写样板。Prisma 的生成类型和嵌套写入收益最明显。
  • 谨慎的:重度依赖 SQL 方言特性(窗口函数、递归 CTE、复杂聚合)的项目,Prisma Client 表达不了的部分要落到 $queryRaw 或 TypedSQL,先评估这部分占比。
  • 不迁的:纯 SQL 查询构建器用得得心应手、性能敏感且每毫秒都要抠的极简项目,Drizzle/Knex 的低抽象层可能更合适。

迁移本身风险可控:内省和基线保证数据库不动,渐进替换保证随时可回退。真正的成本在团队学习曲线,而不是技术障碍。

参考来源

  • Prisma 官方文档:switch-to-prisma-orm(from-drizzle / from-mongoose / from-sql-orms)
  • Prisma 官方文档:Prisma vs Drizzle、Prisma vs TypeORM 对比页
  • Better Stack:Drizzle vs Prisma、Knex vs Prisma