關於影子資料庫
影子資料庫是第二個**臨時**資料庫,每次執行prisma migrate dev時都會**自動建立和刪除**,主要用於**檢測問題**,例如模式漂移或生成的遷移可能導致的資料丟失。
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列舉缺少預期的變體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 刪除和建立資料庫。有些要求透過線上介面建立或刪除資料庫,有些則真的只限制您一個數據庫。如果您在這樣的雲託管環境中**開發**,您必須
- 建立一個專用的雲託管影子資料庫
- 將 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 db push而不是prisma migrate dev命令。
**重要提示**:影子資料庫**僅**在開發環境中需要(特別是對於
prisma migrate dev命令)- 您**無需**對生產環境進行任何更改。