跳至主要内容

关于影子数据库

影子数据库是第二个*临时*数据库,每次运行prisma migrate dev时都会**自动创建和删除**,主要用于**检测问题**,例如模式漂移或生成迁移可能导致的数据丢失。

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

警告

生产环境**不需要**影子数据库,并且生产环境的命令(例如prisma migrate resolveprisma migrate deploy)也不使用影子数据库。

注意

MongoDB从不使用影子数据库,因为那里不使用migrate dev

影子数据库的工作原理

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

  • 检测模式漂移,这意味着检查开发数据库中是否没有发生**意外更改**
  • 生成新迁移并评估这些迁移在应用时是否可能导致**数据丢失**
🎨 展开以卡通形式查看影子数据库的解释。

A cartoon that shows how the shadow database works.

检测模式漂移

为了检测开发中的漂移,Prisma Migrate

  1. 创建影子数据库的一个全新副本(如果通过shadowDatabaseUrl配置了影子数据库,则执行软重置)
  2. 在影子数据库中重新运行**当前**的、现有的迁移历史记录。
  3. **内省**影子数据库以生成Prisma模式的“当前状态”。
  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模式更改生成新迁移。为了生成新迁移,Prisma Migrate

  1. 计算作为当前Prisma模式函数的目标数据库模式
  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"
shadowDatabaseUrl = env("SHADOW_DATABASE_URL")
}

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

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

一些云提供商不允许您使用SQL删除和创建数据库。有些要求通过在线界面创建或删除数据库,有些则确实将您限制为1个数据库。如果您在此类云托管环境中**开发**,则必须

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

**重要**:不要为urlshadowDatabaseUrl使用相同的值。

影子数据库用户权限

为了在使用migrate dev时创建和删除影子数据库,Prisma Migrate目前要求datasource中定义的数据库用户具有**创建数据库**的权限。

数据库数据库用户要求
SQLite无特殊要求。
MySQL/MariaDB数据库用户必须具有CREATE, ALTER, DROP, REFERENCES ON *.*权限
PostgreSQL用户必须是超级用户或具有CREATEDB权限。请参阅CREATE ROLEPostgreSQL官方文档
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命令)中需要 - 您**不需要**对生产环境进行任何更改。

© . This site is unofficial and not affiliated with Prisma Data, Inc.