メインコンテンツへスキップ

MongooseからPrisma ORMへの移行方法

15分

はじめに

このガイドでは、MongooseからPrisma ORMへアプリケーションを移行する方法を説明します。移行手順を示すためのMongoose Expressの拡張例サンプルプロジェクトとして使用します。

Prisma ORMとMongooseの比較については、「Prisma ORM vs 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スキーマファイルを作成する

npx prisma init --datasource-provider mongodb --output ../generated/prisma

このコマンドは以下を作成します。

  • prismaという新しいディレクトリ。これにはschema.prismaファイルが含まれ、Prismaスキーマはデータベース接続とモデルを指定します。
  • .env: プロジェクトのルートにdotenvファイル(存在しない場合)が作成され、データベース接続URLを環境変数として設定するために使用されます。

現在のPrismaスキーマは以下のようになります。

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での最適な開発体験のために、構文ハイライト、フォーマット、自動補完、その他多くの便利な機能については、「エディターのセットアップ」を参照してください。

.envファイルのDATABASE_URLをMongoDB接続文字列で更新します。

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

2. データベーススキーマを移行する

2.1. データベースをイントロスペクトする

警告

MongoDBはスキーマレスデータベースです。プロジェクトでPrisma ORMを段階的に導入するには、データベースにサンプルデータが投入されていることを確認してください。Prisma ORMは、保存されたデータをサンプリングし、データベース内のデータからスキーマを推論することでMongoDBスキーマをイントロスペクトします。

既存のデータベースからPrismaスキーマを作成するために、Prismaのイントロスペクションを実行します。

npx prisma db pull

これにより、データベーススキーマを含む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の配列を使用して1対多のドキュメント参照を作成したりすることはできます。参照は、関連するドキュメントのIDを保存します。Mongooseが提供するpopulate()メソッドを使用して、参照を関連ドキュメントのデータで埋めることができます。

posts <-> users間の1対多のリレーションを次のように更新します。

  • postsモデル内の既存のauthor参照をauthorIdにリネームし、@map("author")属性を追加します。
  • postsモデルにauthorリレーションフィールドと、fieldsおよびreferencesを指定する@relation属性を追加します。
  • usersモデルにpostsリレーションを追加します。

これでスキーマは次のようになります。

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リレーションを追加します。
  • 両方のモデルにリレーションスカラーを追加します。
  • 両側にfieldsreferences引数を指定する@relation属性を追加します。

これでスキーマは次のようになります。

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クエリを置き換える

MongooseクエリをPrisma Clientに置き換え始めます。一般的なクエリを変換する方法の例を以下に示します。

// 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のテストユーティリティを使用して自動テストを追加する

詳細については


Prismaとつながる

以下とつながってPrismaの旅を続けましょう 私たちの活発なコミュニティ。情報を入手し、参加し、他の開発者と協力しましょう。

  • Xでフォローする アナウンス、ライブイベント、役立つヒントをお届けします。
  • Discordに参加する 質問をしたり、コミュニティと話したり、会話を通じて積極的にサポートを受けたりできます。
  • YouTubeで購読する チュートリアル、デモ、ストリームをお届けします。
  • GitHubで関わる リポジトリにスターを付けたり、問題を報告したり、問題に貢献したりしてください。
皆様の参加を心よりお待ちしております。コミュニティの一員になっていただけることを楽しみにしています!

© . All rights reserved.