關於影子資料庫
影子資料庫是第二個、暫時性的資料庫,它會在每次您執行 prisma migrate dev
時自動建立和刪除*,主要用於偵測問題,例如 schema drift 或產生的遷移可能導致的資料遺失。
migrate diff
命令 在使用 --from-migrations
或 --to-migrations
針對本機 migrations
目錄進行差異比較時,也需要影子資料庫。
- 如果您的資料庫不允許建立和刪除資料庫(例如在雲端託管環境中),您需要手動建立和設定影子資料庫。
影子資料庫在生產環境中是不需要的,並且不會被生產環境導向的命令(例如 prisma migrate resolve
和 prisma migrate deploy
)使用。
影子資料庫永遠不會用於 MongoDB,因為 migrate dev
在那裡不使用。
影子資料庫如何運作
當您執行 prisma migrate dev
來建立新的遷移時,Prisma Migrate 會使用影子資料庫來
- 偵測 schema drift,這表示檢查開發資料庫是否沒有進行非預期的變更
- 產生新的遷移 並評估這些遷移在應用時是否可能導致資料遺失
🎨 展開以卡通形式查看影子資料庫的說明。
偵測 Schema Drift
為了在開發中偵測 drift,Prisma Migrate 會
- 建立影子資料庫的全新副本(如果影子資料庫是透過
shadowDatabaseUrl
配置,則執行軟重設) - 在影子資料庫中重新執行目前現有的遷移歷史記錄。
- 內省影子資料庫以產生 Prisma schema 的「目前狀態」。
- 比較目前遷移歷史記錄的最終狀態與開發資料庫。
- 如果目前遷移歷史記錄的最終狀態(透過影子資料庫)與開發資料庫不符(例如,由於手動變更),則報告 schema drift
如果 Prisma Migrate 沒有偵測到 schema drift,它會繼續產生新的遷移。
注意:影子資料庫不負責檢查遷移檔案是否已被編輯或刪除。這是使用
_prisma_migrations
表格中的checksum
欄位完成的。
如果 Prisma Migrate 偵測到 schema drift,它會輸出關於資料庫哪些部分發生 drift 的詳細資訊。當開發資料庫已被手動修改時,可能會顯示以下範例輸出: Color
列舉缺少預期的變體 RED
,並包含非預期的變體 TRANSPARENT
[*] Changed the `Color` enum
[+] Added variant `TRANSPARENT`
[-] Removed variant `RED`
產生新的遷移
假設 Prisma Migrate 沒有偵測到 schema drift,它會繼續從 Prisma schema 變更產生新的遷移。為了產生新的遷移,Prisma Migrate 會
- 將目標資料庫 schema 計算為目前 Prisma schema 的函數。
- 比較現有遷移歷史記錄的最終狀態和目標 schema,並產生從一個狀態到另一個狀態的步驟。
- 將這些步驟呈現為 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 schema 應用於資料庫 schema,則可以執行
prisma db push
而不是prisma migrate dev
命令。
重要事項:影子資料庫僅在開發環境中(特別是對於
prisma migrate dev
命令)是必需的 - 您不需要對您的生產環境進行任何變更。