跳到主要內容

如何從 Mongoose 遷移到 Prisma ORM

15 分鐘

簡介

本指南將說明如何將您的應用程式從 Mongoose 遷移到 Prisma ORM。我們將使用 Mongoose Express 範例 的擴展版本作為 範例專案,以示範遷移步驟。

您可以在 Prisma ORM 與 Mongoose 比較 頁面上了解 Prisma ORM 與 Mongoose 的比較。

先決條件

開始本指南之前,請確保您已具備

  • 您想要遷移的 Mongoose 專案
  • 已安裝 Node.js (版本 18 或更高版本)
  • MongoDB 資料庫
  • 基本熟悉 Mongoose 和 Express.js

1. 準備遷移

1.1. 了解遷移流程

從 Mongoose 遷移到 Prisma ORM 的步驟始終相同,無論您正在建構哪種類型的應用程式或 API 層

  1. 安裝 Prisma CLI
  2. 內省您的資料庫
  3. 安裝並產生 Prisma Client
  4. 逐步將您的 Mongoose 查詢替換為 Prisma Client

無論您正在建構 REST API (例如,使用 Express、Koa 或 NestJS)、GraphQL API (例如,使用 Apollo Server、TypeGraphQL 或 Nexus),還是任何其他使用 Mongoose 進行資料庫存取的應用程式,這些步驟都適用。

1.2. 設定 Prisma 配置

建立新的 Prisma schema 檔案

npx prisma init --datasource-provider mongodb

此命令會建立

  • 一個名為 prisma 的新目錄,其中包含 schema.prisma 檔案;您的 Prisma schema 指定您的資料庫連線和模型
  • .env:專案根目錄下的 dotenv 檔案 (如果尚不存在),用於將您的資料庫連線 URL 配置為環境變數

Prisma schema 目前如下所示

prisma/schema.prisma
// This is your Prisma schema file,
// learn more about it in the docs: https://pris.ly/d/prisma-schema

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

generator client {
provider = "prisma-client-js"
}

提示

為了在使用 Prisma ORM 時獲得最佳開發體驗,請參閱編輯器設定,以了解語法突顯、格式化、自動完成以及更多酷炫功能。

使用您的 MongoDB 連線字串更新 .env 檔案中的 DATABASE_URL

DATABASE_URL="mongodb://USER:PASSWORD@HOST:PORT/DATABASE"

2. 遷移資料庫 schema

2.1. 內省您的資料庫

警告

MongoDB 是一個無 schema 資料庫。為了在您的專案中逐步採用 Prisma ORM,請確保您的資料庫已填充範例資料。Prisma ORM 通過抽樣儲存的資料並從資料庫中的資料推斷 schema 來內省 MongoDB schema。

執行 Prisma 的內省以從您現有的資料庫建立 Prisma schema

npx prisma db pull

這將建立一個包含您的資料庫 schema 的 schema.prisma 檔案。

prisma/schema.prisma
type UsersProfile {
bio String
}

model categories {
id String @id @default(auto()) @map("_id") @db.ObjectId
v Int @map("__v")
name String
}

model posts {
id String @id @default(auto()) @map("_id") @db.ObjectId
v Int @map("__v")
author String @db.ObjectId
categories String[] @db.ObjectId
content String
published Boolean
title String
}

model users {
id String @id @default(auto()) @map("_id") @db.ObjectId
v Int @map("__v")
email String @unique(map: "email_1")
name String
profile UsersProfile?
}

2.2. 更新關聯

MongoDB 不支援不同集合之間的關聯。但是,您可以使用 ObjectId 欄位類型或從一個文件到多個文件使用集合中 ObjectId 的陣列來建立文件之間的參考。參考將儲存相關文件的 ID。您可以使用 Mongoose 提供的 populate() 方法來使用相關文件的資料填充參考。

如下更新 posts <-> users 之間的一對多關係

  • posts 模型中現有的 author 參考重新命名為 authorId 並新增 @map("author") 屬性
  • posts 模型中新增 author 關聯欄位及其 @relation 屬性,指定 fieldsreferences
  • users 模型中新增 posts 關聯

您的 schema 現在應如下所示

schema.prisma
type UsersProfile {
bio String
}

model categories {
id String @id @default(auto()) @map("_id") @db.ObjectId
v Int @map("__v")
name String
}

model posts {
id String @id @default(auto()) @map("_id") @db.ObjectId
title String
content String
published Boolean
v Int @map("__v")
author String @db.ObjectId
author users @relation(fields: [authorId], references: [id])
authorId String @map("author") @db.ObjectId

categories String[] @db.ObjectId
}

model users {
id String @id @default(auto()) @map("_id") @db.ObjectId
v Int @map("__v")
email String @unique(map: "email_1")
name String
profile UsersProfile?
posts posts[]
}

然後,如下更新 posts <-> categories 參考之間的 多對多 關係

  • posts 模型中,將 categories 欄位重新命名為 categoryIds 並使用 @map("categories") 進行映射
  • posts 模型中新增新的 categories 關聯欄位
  • categories 模型中新增 postIds 純量列表欄位
  • categories 模型中新增 posts 關聯
  • 在兩個模型上新增關聯純量
  • 在兩側新增 @relation 屬性,指定 fieldsreferences 參數

您的 schema 現在應如下所示

schema.prisma
type UsersProfile {
bio String
}

model categories {
id String @id @default(auto()) @map("_id") @db.ObjectId
v Int @map("__v")
name String
posts posts[] @relation(fields: [postIds], references: [id])
postIds String[] @db.ObjectId
}

model posts {
id String @id @default(auto()) @map("_id") @db.ObjectId
title String
content String
published Boolean
v Int @map("__v")

author users @relation(fields: [authorId], references: [id])
authorId String @map("author") @db.ObjectId

categories String[] @db.ObjectId
categories categories[] @relation(fields: [categoryIds], references: [id])
categoryIds String[] @map("categories") @db.ObjectId
}

model users {
id String @id @default(auto()) @map("_id") @db.ObjectId
v Int @map("__v")
email String @unique(map: "email_1")
name String
profile UsersProfile?
posts posts[]
}

3. 更新您的應用程式程式碼

3.1. 安裝 Prisma Client

安裝 Prisma Client 套件

npm install @prisma/client

安裝 Prisma Client 套件後,產生 Prisma Client

npx prisma generate

3.2. 替換 Mongoose 查詢

開始使用 Prisma Client 替換您的 Mongoose 查詢。以下是如何轉換一些常見查詢的範例

// Find one
const user = await User.findById(id);

// Create
const user = await User.create({
email: 'alice@prisma.io',
name: 'Alice'
});

// Update
await User.findByIdAndUpdate(id, {
name: 'New name'
});

// Delete
await User.findByIdAndDelete(id);

3.3. 更新您的控制器

更新您的 Express 控制器以使用 Prisma Client。例如,以下是如何更新使用者控制器的範例

import { prisma } from '../client'

export class UserController {
async create(req: Request, res: Response) {
const { email, name } = req.body

const result = await prisma.user.create({
data: {
email,
name,
},
})

return res.json(result)
}
}

下一步

現在您已遷移到 Prisma ORM,您可以

  • 使用 Prisma 強大的查詢 API 新增更複雜的查詢
  • 設定 Prisma Studio 以進行資料庫管理
  • 實作資料庫監控
  • 使用 Prisma 的測試工具新增自動化測試

如需更多資訊和更新