シャドウデータベースについて
シャドウデータベースは、`prisma migrate dev`を実行するたびに**自動的に作成および削除される***2番目の*一時的な*データベースであり、主にスキーマのずれや生成されたマイグレーションによる潜在的なデータ損失などの**問題検出**に使用されます。
`migrate diff`コマンドは、ローカルの`migrations`ディレクトリに対して`--from-migrations`または`--to-migrations`を使用して差分を比較する場合にも、シャドウデータベースを必要とします。
- お使いのデータベースがデータベースの作成と削除を許可していない場合(例:クラウドホスト環境)、シャドウデータベースを手動で作成し設定する必要があります。
シャドウデータベースは本番環境では**必要なく**、`prisma migrate resolve`や`prisma migrate deploy`などの本番環境向けのコマンドでは使用されません。
MongoDBでは`migrate dev`が使用されないため、シャドウデータベースも使用されません。
シャドウデータベースの仕組み
新しいマイグレーションを作成するために`prisma migrate dev`を実行すると、Prisma Migrateはシャドウデータベースを使用して以下を行います。
- スキーマのずれを検出する。これは、開発データベースに**予期せぬ変更**が加えられていないかを確認することを意味します。
- 新しいマイグレーションを生成し、それらが適用された場合に**データ損失**を引き起こす可能性があるかを評価します。
🎨 シャドウデータベースの仕組みをイラストで見るには展開してください。
スキーマのずれの検出
開発中のずれを検出するために、Prisma Migrateは以下を行います。
- シャドウデータベースの新しいコピーを作成します(または、シャドウデータベースが
shadowDatabaseUrl
を介して構成されている場合はソフトリセットを実行します)。 - シャドウデータベースで**現在**の既存のマイグレーション履歴を再実行します。
- シャドウデータベースを**イントロスペクト**し、Prismaスキーマの「現在の状態」を生成します。
- 現在のマイグレーション履歴の最終状態と開発データベースを比較します。
- 現在のマイグレーション履歴の最終状態(シャドウデータベース経由)が開発データベースと一致しない場合(例えば、手動変更によるもの)、**スキーマのずれ**を報告します。
Prisma Migrateがスキーマのずれを検出しない場合、新しいマイグレーションの生成に進みます。
**注**: シャドウデータベースは、マイグレーションファイルが**編集または削除**されたかどうかをチェックする責任はありません。これは、`_prisma_migrations`テーブルの`checksum`フィールドを使用して行われます。
Prisma Migrateがスキーマのずれを検出した場合、データベースのどの部分がずれているかについての詳細情報が出力されます。開発データベースが手動で変更された場合に表示される可能性のある出力例は次のとおりです。Color
enumに期待されるバリアント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`コマンドの場合)で*のみ*必要です。本番環境に変更を加える**必要はありません**。