メンタルモデル
このガイドでは、リレーショナルデータベースでPrisma Migrateを使用してデータベースマイグレーションを行う際の概念的な概要を説明します。データベースマイグレーションとは何か、その価値、Prisma Migrateとは何か、そしてさまざまな環境でPrisma Migrateを使ってデータベーススキーマを進化させる方法について解説します。
MongoDBを使用している場合は、prisma db push
を使用してスキーマを進化させてください。
データベースマイグレーションとは?
データベースマイグレーションとは、データベーススキーマの構造を変更・進化させるための一連の管理された変更のことです。マイグレーションは、データベーススキーマをある状態から別の状態へ移行させるのに役立ちます。例えば、マイグレーション内でテーブルやカラムの作成・削除、テーブル内のフィールドの分割、データベースへの型や制約の追加などが可能です。
データベーススキーマを進化させるパターン
このセクションでは、データベーススキーマを進化させるための一般的なスキーママイクレーションパターンについて説明します。
主なスキーママイグレーションパターンは2つあります
- モデル/エンティティファーストマイグレーション:このパターンでは、コードでデータベーススキーマの構造を定義し、その後マイグレーションツールを使用してSQLを生成します。例えば、アプリケーションとデータベーススキーマを同期させる場合などです。
- データベースファーストマイグレーション:このパターンでは、データベースの構造を定義し、SQLを使用してデータベースに適用します。その後、データベースをイントロスペクトして、アプリケーションとデータベーススキーマを同期させるために、データベースの構造を記述するコードを生成します。
注
簡潔さのため、上記はデータベーススキーマを進化させるさまざまなパターンを説明する用語として選択しました。他のツールやライブラリでは、異なるパターンを説明するために別の用語を使用する場合があります。
マイグレーションファイル(SQL)は、理想的にはアプリケーションコードと一緒に保存されるべきです。また、バージョン管理で追跡され、アプリケーションに取り組む他のチームメンバーと共有されるべきです。
マイグレーションは状態管理を提供し、データベースの状態を追跡するのに役立ちます。
マイグレーションは、特定の時点でのデータベースの状態を複製することも可能にします。これは、チームの他のメンバーと共同作業を行う際、例えば異なるブランチ間を切り替える場合などに役立ちます。
データベースマイグレーションの詳細については、Prisma Data Guideを参照してください。
Prisma Migrateとは?
Prisma Migrateは、モデル/エンティティファーストのマイグレーションパターンをサポートするデータベースマイグレーションツールであり、ローカル環境と本番環境でデータベーススキーマを管理するために使用されます。
プロジェクトでPrisma Migrateを使用する場合のワークフローは反復的で、以下のようになります。
ローカル開発環境(フィーチャーブランチ)
- Prismaスキーマを進化させる
- ローカル開発データベースのPrismaスキーマをデータベーススキーマと同期させるには、
prisma migrate dev
またはprisma db push
を使用します。
プレビュー/ステージング環境(フィーチャープルリクエスト)
- 変更をフィーチャープルリクエストにプッシュする
- CIシステム(例:GitHub Actions)を使用して、
prisma migrate deploy
によりPrismaスキーマとマイグレーション履歴をプレビューデータベースと同期させます。
本番環境(メインブランチ)
- アプリケーションコードをフィーチャーブランチからメインブランチにマージする
- CIシステム(例:GitHub Actions)を使用して、
prisma migrate deploy
によりPrismaスキーマとマイグレーション履歴を本番データベースと同期させます。
Prisma Migrateがマイグレーションの状態を追跡する方法
Prisma Migrateは、データベーススキーマの状態を追跡するために、以下の状態の要素を使用します。
- Prismaスキーマ:データベーススキーマの構造を定義する真実の源。
- マイグレーション履歴:
prisma/migrations
フォルダ内のSQLファイルで、データベーススキーマに加えられた変更履歴を表します。 - マイグレーションテーブル:データベース内の
prisma_migrations
テーブルで、データベースに適用されたマイグレーションのメタデータを保存します。 - データベーススキーマ:データベースの状態。
Prisma Migrateを使用する際の要件
- 理想的には、環境ごとに1つのデータベースを使用すべきです。例えば、開発、プレビュー、本番環境用にそれぞれ独立したデータベースを持つことができます。
- 開発環境で使用するデータベースは一時的なものであり、必要に応じて簡単にデータベースを作成、使用、削除できます。
- 各環境で使用されるデータベース構成は一貫している必要があります。これは、ワークフロー全体で移動する特定のマイグレーションがデータベースに同じ変更をもたらすことを保証するために重要です。
- Prismaスキーマは真実の源として機能し、データベーススキーマの形状を記述します。
Prisma Migrateでデータベーススキーマを進化させる
このセクションでは、Prisma Migrateを使用して、開発、ステージング、本番といった異なる環境でデータベーススキーマを進化させる方法について説明します。
開発環境(ローカル)でのPrisma Migrate
prisma migrate dev
でマイグレーション履歴を追跡する
prisma migrate dev
コマンドを使用すると、データベースに加えられた変更を追跡できます。prisma migrate dev
コマンドは、SQLマイグレーションファイルを自動的に生成(/prisma/migrations
に保存)し、それらをデータベースに適用します。マイグレーションがデータベースに適用されると、データベース内のマイグレーションテーブル(_prisma_migrations
)も更新されます。
prisma migrate dev
コマンドは、以下の状態の要素を使用してデータベースの状態を追跡します。
- Prismaスキーマ
- マイグレーション履歴
- マイグレーションテーブル
- データベーススキーマ
注:マイグレーションの状態を追跡するために使用される状態の要素は、Prisma Migrateがマイグレーションの状態を追跡する方法のセクションで説明されているものと同じです。
--create-only
フラグを使用して、データベースに適用する前にマイグレーションをカスタマイズできます。例えば、データ損失なしにカラム名を変更したい場合や、データベース拡張機能(PostgreSQLの場合)やデータベースビュー(現在はサポートされていません)をロードしたい場合に、マイグレーションを編集することができます。
内部的には、Prisma Migrateはシャドウデータベースを使用してスキーマドリフトを検出し、新しいマイグレーションを生成します。
注:
prisma migrate dev
は、開発環境で一時的なデータベースとのみ使用することを意図しています。
prisma migrate dev
がスキーマドリフトまたはマイグレーション履歴の競合を検出した場合、マイグレーション履歴とデータベーススキーマを同期させるためにデータベースのリセット(データベースの削除と再作成)を求められます。
漫画で説明されたシャドウデータベースを見るために展開
スキーマドリフトの解決
スキーマドリフトは、期待されるデータベーススキーマがマイグレーション履歴と異なる場合に発生します。例えば、Prismaスキーマとprisma/migrations
を適切に更新せずに、手動でデータベーススキーマを更新した場合に発生する可能性があります。
そのような場合、prisma migrate diff
コマンドを使用して、マイグレーション履歴を比較し、データベーススキーマに加えられた変更を元に戻すことができます。
migrate diff
を使用すると、以下のいずれかのSQLを生成できます。
- データベーススキーマに加えられた変更を元に戻し、現在のPrismaスキーマと同期させる
- データベーススキーマを前進させ、Prismaスキーマと
/migrations
からの不足している変更を適用する
その後、prisma db execute
コマンドを使用してデータベースに変更を適用できます。
スキーマをプロトタイプする
prisma db push
コマンドを使用すると、マイグレーション(/prisma/migrations
)を永続化せずにPrismaスキーマとデータベーススキーマを同期させることができます。prisma db push
コマンドは、以下の状態の要素を使用してデータベースの状態を追跡します。
- Prismaスキーマ
- データベーススキーマ
prisma db push
コマンドは、次の場合に役立ちます。
- スキーマ設計をローカルで迅速にプロトタイプし、反復したい場合、他の開発者やステージング、本番環境などの他の環境に変更をデプロイする必要はありません。
- 望ましい最終状態に到達することを優先し、その最終状態に到達するために実行された変更や手順は優先しない場合(
prisma db push
による変更をプレビューする方法はありません) - スキーマ変更がデータにどのように影響するかを制御する必要がない場合。スキーマとデータのマイグレーションを調整する方法はありません。もし
prisma db push
が変更によってデータ損失が生じると予測した場合、--accept-data-loss
オプションでデータ損失を受け入れるか、プロセスを停止するかのどちらかです。変更をカスタマイズする方法はありません。
prisma db push
コマンドがデータベーススキーマへの破壊的な変更を検出した場合、データベースのリセットを求められます。例えば、既存のコンテンツを持つテーブルに必須フィールドをデフォルト値なしで追加した場合に、この状況が発生します。
データベーススキーマがマイグレーション履歴やマイグレーションテーブルと同期していない場合に、スキーマドリフトが発生します。
ステージングおよび本番環境でのPrisma Migrate
マイグレーション履歴を同期する
prisma migrate deploy
コマンドを使用すると、開発環境からのマイグレーション履歴をステージングまたは本番環境のデータベースと同期させることができます。
内部的に、migrate deploy
コマンドは次のことを行います。
- 既に適用されたマイグレーション(キャプチャされた
_prisma_migrations
)とマイグレーション履歴(/prisma/migrations
)を比較する - 保留中のマイグレーションを適用する
- 新しいマイグレーションで
_prisma_migrations
テーブルを更新する
このコマンドは、GitHub Actionsなどの自動化されたCI/CD環境で実行する必要があります。
マイグレーション履歴(/migrations
)がない場合、つまりprisma db push
を使用している場合、ステージングおよび本番環境でも引き続きprisma db push
を使用する必要があります。データベーススキーマに適用される変更の一部は破壊的である可能性があるため、注意してください。例えば、prisma db push
はカラム名変更を行っていることを判別できません。データベースのリセット(削除と再作成)を促されます。