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

展開と縮小のパターンを使用してデータを移行する

10分

はじめに

本番環境でデータベーススキーマに変更を加える際、データの整合性を確保し、ダウンタイムを避けることが重要です。このガイドでは、展開と縮小のパターンを使用して、列間でデータを安全に移行する方法を示します。既存のデータを保持しながら、ブール型フィールドを列挙型フィールドに置き換える実践的な例を説明します。

前提条件

このガイドを始める前に、以下が準備されていることを確認してください

  • Node.jsがインストールされていること (バージョン18以上)
  • 既存のスキーマを持つPrisma ORMプロジェクト
  • サポートされているデータベース (PostgreSQL, MySQL, SQLite, SQL Serverなど)
  • 開発環境と本番環境のデータベースへのアクセス
  • Gitブランチの基本的な理解
  • TypeScriptの基本的な知識

1. 環境設定

1.1. 初期スキーマの確認

Postモデルを含む基本的なスキーマから始めます

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

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

model Post {
id Int @id @default(autoincrement())
title String
content String?
published Boolean @default(false)
}

1.2. 開発ブランチの作成

変更用の新しいブランチを作成します

git checkout -b create-status-field

2. スキーマの拡張

2.1. 新しい列の追加

新しいStatus列挙型とフィールドを追加するようにスキーマを更新します

model Post {
id Int @id @default(autoincrement())
title String
content String?
published Boolean? @default(false)
status Status @default(Unknown)
}

enum Status {
Unknown
Draft
InProgress
InReview
Published
}

2.2. 移行の作成

移行を生成します

npx prisma migrate dev --name add-status-column

3. データの移行

3.1. 移行スクリプトの作成

データ移行用の新しいTypeScriptファイルを作成します

import { PrismaClient } from '@prisma/client'

const prisma = new PrismaClient()

async function main() {
await prisma.$transaction(async (tx) => {
const posts = await tx.post.findMany()
for (const post of posts) {
await tx.post.update({
where: { id: post.id },
data: {
status: post.published ? 'Published' : 'Unknown',
},
})
}
})
}

main()
.catch(async (e) => {
console.error(e)
process.exit(1)
})
.finally(async () => await prisma.$disconnect())

3.2. 移行スクリプトのセットアップ

package.jsonに移行スクリプトを追加します

{
"scripts": {
"data-migration:add-status-column": "tsx ./prisma/migrations/<migration-timestamp>/data-migration.ts"
}
}

3.3. 移行の実行

  1. DATABASE_URLを本番データベースを指すように更新します
  2. 移行スクリプトを実行します
npm run data-migration:add-status-column

4. スキーマの縮小

4.1. クリーンアップブランチの作成

古い列を削除するための新しいブランチを作成します

git checkout -b drop-published-column

4.2. 古い列の削除

publishedフィールドを削除するようにスキーマを更新します

model Post {
id Int @id @default(autoincrement())
title String
content String?
status Status @default(Unknown)
}

enum Status {
Draft
InProgress
InReview
Published
}

4.3. クリーンアップ移行の生成

最終的な移行を作成して実行します

npx prisma migrate dev --name drop-published-column

5. 本番環境へのデプロイ

5.1. デプロイのセットアップ

以下のコマンドをCI/CDパイプラインに追加します

npx prisma migrate deploy

5.2. デプロイの監視

デプロイ後、ログにエラーがないか確認し、アプリケーションの動作を監視してください。

トラブルシューティング

一般的な問題と解決策

  1. デフォルト値の欠落による移行の失敗

    • 適切なデフォルト値が追加されていることを確認してください
    • 既存のすべてのレコードが移行できることを確認してください
  2. データ損失の防止

    • 移行を実行する前に、必ずデータベースをバックアップしてください
    • まず、本番データのコピーで移行をテストしてください
  3. トランザクションのロールバック

    • データ移行が失敗した場合、トランザクションは自動的にロールバックされます
    • エラーを修正し、移行を再試行してください

次のステップ

最初の展開と縮小の移行を完了したので、次は以下を行うことができます

詳細情報


Prismaとつながる

Prismaの旅を続けるには、以下とつながりましょう 活発なコミュニティに参加しましょう。最新情報を入手し、参加し、他の開発者と協力しましょう

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

© . All rights reserved.