跳到主要内容

从 MongoDB Beta 升级

引言

本指南帮助你从 Prisma 1 MongoDB Beta 迁移到 Prisma ORM 2 或更高版本上的 MongoDB。要了解有关 Prisma 1 与 Prisma ORM 2.x 及更高版本之间差异的更多信息,请参阅此文档

本指南的范围是为你提供执行迁移所需的工作流程,并重点介绍你可能遇到的一些问题。

遗憾的是,我们无法涵盖所有可能的情景或所需的更改,但本指南应该能帮助你完成迁移。加入我们的 Discord 或在Github 上 创建议题提出任何问题。

警告

在生产环境中尝试之前,请务必先在你的预生产环境(staging environment)中执行此迁移!

要求

  • 必须以副本集形式运行 MongoDB 4.2+(MongoDB Atlas 会为你自动完成)
  • Node.js:参阅系统要求
  • TypeScript:参阅系统要求

安装 Prisma ORM 3.12.0 或更高版本

在你的项目目录中运行以下命令

$ npm install prisma@latest
$ npx prisma init --datasource-provider=mongodb

这将创建以下文件

  • prisma/schema.prisma:一个初始的 Prisma schema
  • .env:用于存储你的连接字符串的环境文件
信息

如果你看到以下错误

ERROR  File schema.prisma already exists in your project.
Please try again in a project that is not yet using Prisma.

你的项目中可能已经存在一个 prisma/ 目录。将该目录重命名为类似 _prisma/ 的名称,然后重试

找到你的 MongoDB 数据库连接字符串

接下来,你需要找到你的 MongoDB 数据库连接字符串。你应该能在你的 docker-compose.yml 文件或 MongoDB Atlas 上找到它。它就是你传递给 MongoDB Compass 的内容。连接字符串应该类似于这样:

mongodb://<user>:<pass>@<host>:27017

在 Prisma 1 中存储应用数据的数据库名称是 default_default,因此我们将它添加到连接字符串的末尾,并更新 .env 文件中的 DATABASE_URL

.env
DATABASE_URL="mongodb://prisma:prisma@localhost:27017/default_default"

内省你的 MongoDB 数据库

现在,你已经准备好将数据库结构提取到你的 Prisma Schema 中了。

$ npx prisma db pull

你应该能在 prisma/schema.prisma 中看到你的 Prisma schema 已经填充了你的模型。

信息

如果你看到以下错误:Error in connector: SCRAM failure: Authentication failed.,请尝试在你的连接字符串末尾添加 ?authSource=admin 然后重试。

修饰你的 Prisma Schema

从基于 Prisma 1 的 MongoDB 数据库最新内省生成的 Prisma Client 可能没有最好的 API。你可以调整模型名称和字段,只需确保使用 @map@@map 将原始名称映射到底层的数据库集合和字段名称。

- model posts {
+ model Post {
id String @id @default(auto()) @map("_id") @db.ObjectId
published Boolean
title String
+ @@map("posts")
}

- model users {
+ model User {
id String @id @default(auto()) @map("_id") @db.ObjectId
email String @unique(map: "email_U")
name String
- posts String[] @db.ObjectId
+ postIds String[] @db.ObjectId @map("posts")

@@index([posts], map: "posts_R")
+ @@map("users")
}

执行这些重命名时要小心,因为你需要确保 Prisma Schema 仍然正确地映射到底层的数据库集合和字段名称。

与 SQL 数据库不同,MongoDB 没有明确理解数据之间的关系。这意味着 Prisma ORM 的内省无法为你推断这些关系。

我们通常建议借助于此文档手动添加关系。然而,Prisma 1 存储外键的方式与 Prisma ORM 2 及更高版本期望的外键位置不同,因此如果你想利用关系特性,需要在添加关系之前调整数据库中外键的位置。

提示

💡 下载Prisma VSCode 扩展以在你迁移 Prisma schema 时提供自动补全和有用的错误消息。

生成 Prisma Client

在 Prisma schema 中填充了你的数据结构后,你现在就可以生成一个 Typescript Client 来读写你的 MongoDB 数据库了。

$ npx prisma generate

测试读取

创建一个简单的 test.ts 脚本来验证 Prisma Client 是否可以读写你的应用。请注意,本指南使用的是Prisma 1 示例仓库中的示例,但代码会根据你的应用而有所不同。

import { PrismaClient } from '@prisma/client'
const prisma = new PrismaClient()

async function main() {
await prisma.$connect()
const posts = await prisma.post.findMany()
console.log(posts)
}

main()
.catch(console.error)
.finally(() => prisma.$disconnect())

确保全局安装了 ts-node 并运行

ts-node test.ts

你应该会看到你的数据列表

[
{
comments: [],
id: '62435a83fca136000996ba16',
content: 'https://prisma.org.cn/day/',
published: true,
title: 'Join us for Prisma Day 2019 in Berlin',
wasCreated: 2022-03-29T19:14:11.172Z,
wasUpdated: 2022-03-29T19:14:11.172Z
},
{
comments: [ [Object] ],
id: '62435a83fca136000996ba18',
content: 'https://graphqlweekly.com/',
published: true,
title: 'Subscribe to GraphQL Weekly for community news',
wasCreated: 2022-03-29T19:14:11.369Z,
wasUpdated: 2022-03-29T19:14:11.369Z
},
{
comments: [],
id: '62435a83fca136000996ba1a',
content: 'https://twitter.com/prisma',
published: false,
title: 'Follow Prisma on Twitter',
wasCreated: 2022-03-29T19:14:11.375Z,
wasUpdated: 2022-03-29T19:14:11.375Z
}
]

测试写入

然后你可以修改你的 test.ts 来尝试写入操作

import { PrismaClient } from '@prisma/client'
const prisma = new PrismaClient()

async function main() {
await prisma.$connect()
const user = await prisma.user.create({
data: {
email: 'alice@prisma.io',
name: 'Alice',
},
})
console.log(user)
}

main()
.catch(console.error)
.finally(() => prisma.$disconnect())

你应该会看到一个用户被创建了。

警告

如果你看到以下错误

Prisma needs to perform transactions, which requires your MongoDB server to be run as a replica set. https://pris.ly/d/mongodb-replica-set

这意味着你的 MongoDB 数据库没有以副本集(replica set)形式运行。请参阅上面的链接获取解决此问题的步骤。

升级你的应用

现在你已经有了一个可用的 Prisma Client,你可以开始用最新的 Prisma Client 查询替换 Prisma Client 1 的查询。Prisma Client 参考是学习如何使用最新 Prisma Client 的有用资源。

总结

希望这份简短的指南能帮助你走上正确的道路。如果你有任何问题或困难,请告诉我们。我们非常感谢你多年来的支持。