跳到主要内容

关于影子数据库

影子数据库是第二个*临时*数据库,它在每次运行prisma migrate dev时都会自动创建和删除\*,主要用于检测问题,例如架构漂移或生成迁移中潜在的数据丢失。

当使用--from-migrations--to-migrations与本地migrations目录进行差异比较时,migrate diff命令也需要影子数据库。

警告

影子数据库在生产环境中不是必需的,并且不用于侧重生产环境的命令,例如prisma migrate resolveprisma migrate deploy

注意

影子数据库永远不会用于 MongoDB,因为在 MongoDB 环境中不使用migrate dev

影子数据库的工作原理

当您运行prisma migrate dev创建新的迁移时,Prisma Migrate 使用影子数据库来

🎨 展开以查看以卡通形式解释的影子数据库。

A cartoon that shows how the shadow database works.

检测架构漂移

为了在开发环境中检测漂移,Prisma Migrate 会

  1. 创建影子数据库的全新副本(如果影子数据库通过shadowDatabaseUrl配置,则执行软重置)
  2. 在影子数据库中重新运行当前的现有迁移历史记录。
  3. 内省影子数据库以生成您的 Prisma schema 的“当前状态”。
  4. 将当前迁移历史记录的最终状态与开发数据库进行比较。
  5. 如果当前迁移历史记录的最终状态(通过影子数据库)与开发数据库不匹配(例如,由于手动更改),则报告架构漂移

如果 Prisma Migrate 未检测到架构漂移,它将继续生成新的迁移

注意:影子数据库不负责检查迁移文件是否被编辑或删除。这是通过_prisma_migrations表中的checksum字段完成的。

如果 Prisma Migrate 检测到架构漂移,它会输出有关数据库哪些部分发生漂移的详细信息。当开发数据库被手动修改时,可能会显示以下示例输出:Color枚举缺少预期的变体RED并包含意外的变体TRANSPARENT

[*] Changed the `Color` enum
[+] Added variant `TRANSPARENT`
[-] Removed variant `RED`

生成新的迁移

假设 Prisma Migrate 未检测到架构漂移,它将根据 Prisma schema 更改继续生成新的迁移。要生成新的迁移,Prisma Migrate 会

  1. 根据当前 Prisma schema 计算目标数据库架构。
  2. 比较现有迁移历史记录的最终状态和目标架构,并生成从一个状态到另一个状态的步骤。
  3. 将这些步骤渲染为 SQL 字符串并将其保存在新的迁移文件中。
  4. 评估由 SQL 引起的数据丢失并发出警告。
  5. 将生成的迁移应用到开发数据库(假设您未指定--create-only标志)
  6. 丢弃影子数据库(通过shadowDatabaseUrl配置的影子数据库不会被丢弃,而是在migrate dev命令开始时被重置)

手动配置影子数据库

在某些情况下(例如,在云托管数据库上不允许创建和丢弃数据库时),手动定义用作migrate dev影子数据库的数据库连接字符串和名称可能是有意义的。在这种情况下,您可以

  1. 创建一个应被用作影子数据库的专用数据库
  2. 将该数据库的连接字符串添加到您的环境变量SHADOW_DATABASE_URL(或.env文件)中
  3. 添加读取此环境变量的shadowDatabaseUrl字段
datasource db {
provider = "postgresql"
url = env("DATABASE_URL")
shadowDatabaseUrl = env("SHADOW_DATABASE_URL")
}

重要提示:不要对urlshadowDatabaseUrl使用完全相同的值,因为这可能会删除数据库中的所有数据。

云托管影子数据库必须手动创建

一些云提供商不允许您使用 SQL 丢弃和创建数据库。有些要求通过在线界面创建或丢弃数据库,有些则严格限制您只能有一个数据库。如果您在这种云托管环境中进行开发,您必须

  1. 创建一个专用的云托管影子数据库
  2. 将 URL 添加到您的环境变量SHADOW_DATABASE_URL
  3. 添加读取此环境变量的shadowDatabaseUrl字段
datasource db {
provider = "postgresql"
url = env("DATABASE_URL")
shadowDatabaseUrl = env("SHADOW_DATABASE_URL")
}

重要提示:不要对urlshadowDatabaseUrl使用相同的值。

影子数据库用户权限

为了在使用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 应用到数据库架构,您可以运行prisma db push命令而不是prisma migrate dev命令。

重要提示:影子数据库在开发环境中是必需的(特别是对于prisma migrate dev命令)- 您不需要对生产环境进行任何更改。