シャドウデータベースについて
シャドウデータベースは、2番目の一時的なデータベースであり、prisma migrate dev
を実行するたびに自動的に作成および削除*され、主にスキーマドリフトや生成されたマイグレーションの潜在的なデータ損失などの問題を検出するために使用されます。
migrate diff
コマンドは、--from-migrations
または--to-migrations
を使用してローカルのmigrations
ディレクトリに対して差分を取る場合にもシャドウデータベースが必要です。
- データベースがデータベースの作成と削除を許可しない場合(たとえば、クラウドホスト環境の場合)、シャドウデータベースを手動で作成および構成する必要があります。
シャドウデータベースは、本番環境では不要であり、prisma migrate resolve
やprisma migrate deploy
などの本番環境向けのコマンドでは使用されません。
シャドウデータベースは、migrate dev
が使用されないため、MongoDBでは決して使用されません。
シャドウデータベースの仕組み
新しいマイグレーションを作成するためにprisma migrate dev
を実行すると、Prisma Migrateはシャドウデータベースを使用して、
- スキーマドリフトを検出します。これは、開発データベースに予期しない変更が加えられていないかを確認することを意味します。
- 新しいマイグレーションを生成し、それらを適用したときにデータ損失につながる可能性があるかどうかを評価します。
🎨 展開して、シャドウデータベースが漫画で説明されているのを見てください。
スキーマドリフトの検出
開発環境でのドリフトを検出するために、Prisma Migrateは
- シャドウデータベースの新しいコピーを作成します(または、シャドウデータベースが
shadowDatabaseUrl
を介して構成されている場合は、ソフトリセットを実行します)。 - シャドウデータベースで現在の既存のマイグレーション履歴を再実行します。
- シャドウデータベースをイントロスペクトして、Prismaスキーマの「現在の状態」を生成します。
- 現在のマイグレーション履歴の終了状態を開発データベースと比較します。
- 現在のマイグレーション履歴の終了状態(シャドウデータベース経由)が開発データベースと一致しない場合(たとえば、手動による変更が原因)、スキーマドリフトを報告します。
Prisma Migrateがスキーマドリフトを検出しない場合、新しいマイグレーションの生成に進みます。
注:シャドウデータベースは、マイグレーションファイルが編集または削除されたかどうかを確認する責任はありません。これは、
_prisma_migrations
テーブルのchecksum
フィールドを使用して行われます。
Prisma Migrateがスキーマドリフトを検出した場合、データベースのどの部分がドリフトしたかに関する詳細情報を出力します。次の出力例は、開発データベースが手動で変更された場合に表示される可能性があります。Color
列挙型には、予期されるバリアントRED
がなく、予期しないバリアントTRANSPARENT
が含まれています。
[*] Changed the `Color` enum
[+] Added variant `TRANSPARENT`
[-] Removed variant `RED`
新しいマイグレーションの生成
Prisma Migrateがスキーマドリフトを検出しなかったと仮定すると、Prismaスキーマの変更から新しいマイグレーションを生成することに進みます。新しいマイグレーションを生成するために、Prisma Migrateは
- 現在のPrismaスキーマの関数として、ターゲットデータベーススキーマを計算します。
- 既存のマイグレーション履歴の終了状態とターゲットスキーマを比較し、一方から他方へ移行するための手順を生成します。
- これらの手順をSQL文字列としてレンダリングし、新しいマイグレーションファイルに保存します。
- SQLによって引き起こされるデータ損失を評価し、それについて警告します。
- 生成されたマイグレーションを開発データベースに適用します(
--create-only
フラグを指定していない場合)。 - シャドウデータベースを削除します(
shadowDatabaseUrl
を介して構成されたシャドウデータベースは削除されませんが、migrate dev
コマンドの開始時にリセットされます)。
シャドウデータベースの手動構成
場合によっては、クラウドホストされたデータベースでデータベースの作成と削除が許可されていない場合など、migrate dev
のシャドウデータベースとして使用する必要があるデータベースの接続文字列と名前を手動で定義することが理にかなっている場合があります。そのような場合は、次のことができます。
- シャドウデータベースとして使用する必要がある専用のデータベースを作成します。
- そのデータベースの接続文字列を環境変数
SHADOW_DATABASE_URL
(または.env
ファイル)に追加します。 - この環境変数を読み取る
shadowDatabaseUrl
フィールドを追加します。
datasource db {
provider = "postgresql"
url = env("DATABASE_URL")
shadowDatabaseUrl = env("SHADOW_DATABASE_URL")
}
重要:
url
とshadowDatabaseUrl
にまったく同じ値を使用しないでください。データベース内のすべてのデータが削除される可能性があります。
クラウドホストされたシャドウデータベースは手動で作成する必要があります
一部のクラウドプロバイダーは、SQLを使用してデータベースを削除および作成することを許可していません。オンラインインターフェースを介してデータベースを作成または削除する必要があるものもあれば、実際に1つのデータベースに制限するものもあります。そのようなクラウドホスト環境で開発する場合は、
- 専用のクラウドホストされたシャドウデータベースを作成します。
- URLを環境変数
SHADOW_DATABASE_URL
に追加します。 - この環境変数を読み取る
shadowDatabaseUrl
フィールドを追加します。
datasource db {
provider = "postgresql"
url = env("DATABASE_URL")
shadowDatabaseUrl = env("SHADOW_DATABASE_URL")
}
重要:
url
とshadowDatabaseUrl
に同じ値を使用しないでください。
シャドウデータベースのユーザー権限
migrate dev
を使用するときにシャドウデータベースを作成および削除するために、Prisma Migrateは現在、datasource
で定義されたデータベースユーザーがデータベースを作成する権限を持っていることを要求しています。
データベース | データベースユーザーの要件 |
---|---|
SQLite | 特別な要件はありません。 |
MySQL/MariaDB | データベースユーザーはCREATE, ALTER, DROP, REFERENCES ON *.* 権限を持っている必要があります。 |
PostgreSQL | ユーザーはスーパーユーザーであるか、CREATEDB 権限を持っている必要があります。CREATE ROLE (PostgreSQL公式ドキュメント)を参照してください。 |
Microsoft SQL Server | ユーザーはサイト管理者であるか、SERVER セキュリティ保護可能オブジェクトを持っている必要があります。公式ドキュメントを参照してください。 |
開発にクラウドホストされたデータベースを使用しており、これらの権限を使用できない場合は、「クラウドホストされたシャドウデータベース」を参照してください。
注:シャドウデータベースの自動作成は、たとえばAzure SQLでは無効になっています。
Prisma Migrateは、接続URLで指定された資格情報でシャドウデータベースを作成できない場合、次のエラーをスローします。
Error: A migration failed when applied to the shadow database
Database error: Error querying the database: db error: ERROR: permission denied to create database
このエラーを解決するには
- ローカルで作業している場合は、データベースユーザーの権限を更新することをお勧めします。
- (何らかの理由で)データベースの作成と削除を許可しないデータベースに対して開発している場合は、「シャドウデータベースの手動構成」を参照してください。
- クラウドベースのデータベース(たとえば、Heroku、Digital Ocean、またはVercel Postgres)に対して開発している場合は、「クラウドホストされたシャドウデータベース」を参照してください。
- クラウドベースのデータベース(たとえば、Heroku、Digital Ocean、またはVercel Postgres)に対して開発しており、現在、生成されたマイグレーションファイルを気にせず、Prismaスキーマをデータベーススキーマに適用するだけでよいプロトタイプ作成を行っている場合は、
prisma migrate dev
コマンドの代わりにprisma db push
を実行できます。
重要:シャドウデータベースは、開発環境(特に
prisma migrate dev
コマンドの場合)でのみ必要です。本番環境に変更を加える必要はありません。