关于影子数据库
影子数据库是第二个临时数据库,每次运行 prisma migrate dev
时都会自动创建和删除*,主要用于检测架构漂移或生成的迁移的潜在数据丢失等问题。
¥The shadow database is a second, temporary database that is created and deleted automatically* each time you run prisma migrate dev
and is primarily used to detect problems such as schema drift or potential data loss of the generated migration.
当将本地 migrations
目录与 --from-migrations
或 --to-migrations
进行比较时,migrate diff
命令 还需要影子数据库。
¥migrate diff
command also requires a shadow database when diffing against a local migrations
directory with --from-migrations
or --to-migrations
.
-
如果你的数据库不允许创建和删除数据库(例如在云托管环境中),你需要 手动创建和配置影子数据库。
¥If your database does not allow creation and deleting of databases (e.g. in a cloud-hosted environment), you need to create and configure the shadow database manually.
生产中不需要影子数据库,并且 prisma migrate resolve
和 prisma migrate deploy
等专注于生产的命令不会使用影子数据库。
¥The shadow database is not required in production, and is not used by production-focused commands such as prisma migrate resolve
and prisma migrate deploy
.
影子数据库从不用于 MongoDB,因为那里不使用 migrate dev
。
¥A shadow database is never used for MongoDB as migrate dev
is not used there.
影子数据库的工作原理
¥How the shadow database works
当你运行 prisma migrate dev
创建新迁移时,Prisma Migrate 使用影子数据库来:
¥When you run prisma migrate dev
to create a new migration, Prisma Migrate uses the shadow database to:
-
检测架构漂移,表示检查开发数据库没有发生意外的更改
¥Detect schema drift, which means checking that no unexpected changes have been made to the development database
-
生成新的迁移 并评估这些应用时是否会导致数据丢失
¥Generate new migrations and evaluate if those could lead to data loss when applied
🎨 Expand to see the shadow database explained as a cartoon.
检测模式漂移
¥Detecting schema drift
为了检测开发中的偏差,Prisma Migrate:
¥To detect drift in development, Prisma Migrate:
-
创建影子数据库的全新副本(如果通过
shadowDatabaseUrl
配置影子数据库,则执行软重置)¥Creates a fresh copy of the shadow database (or performs a soft reset if the shadow database is configured via
shadowDatabaseUrl
) -
重新运行影子数据库中当前现有的迁移历史记录。
¥Reruns the current, existing migration history in the shadow database.
-
内省影子数据库以生成 Prisma 架构的 '当前状态'。
¥Introspects the shadow database to generate the 'current state' of your Prisma schema.
-
将当前迁移历史记录的最终状态与开发数据库进行比较。
¥Compares the end state of the current migration history to the development database.
-
如果当前迁移历史记录的最终状态(通过影子数据库)与开发数据库不匹配(例如,由于手动更改),则报告架构漂移
¥Reports schema drift if the end state of the current migration history (via the shadow database) does not match the development database (for example, due to a manual change)
如果 Prisma Migrate 未检测到架构漂移,则会移至 产生新的迁移。
¥If Prisma Migrate does not detect schema drift, it moves on to generating new migrations.
注意:影子数据库不负责检查迁移文件是否已被编辑或删除。这是使用
_prisma_migrations
表中的checksum
字段完成的。¥Note: The shadow database is not responsible for checking if a migration file has been edited or deleted. This is done using the
checksum
field in the_prisma_migrations
table.
如果 Prisma Migrate 检测到架构漂移,它会输出有关数据库哪些部分发生漂移的详细信息。手动修改开发数据库后,可能会显示以下示例输出:Color
枚举缺少预期的变体 RED
,并包含意外的变体 TRANSPARENT
:
¥If Prisma Migrate detects schema drift, it outputs detailed information about which parts of the database have drifted. The following example output could be shown when the development database has been modified manually: The Color
enum is missing the expected variant RED
and includes the unexpected variant TRANSPARENT
:
[*] Changed the `Color` enum
[+] Added variant `TRANSPARENT`
[-] Removed variant `RED`
生成新的迁移
¥Generating new migrations
假设 Prisma Migrate 没有 检测模式漂移,它会继续根据 Prisma 架构更改生成新的迁移。要生成新的迁移,Prisma Migrate:
¥Assuming Prisma Migrate did not detect schema drift, it moves on to generating new migrations from Prisma schema changes. To generate new migrations, Prisma Migrate:
-
根据当前 Prisma 架构计算目标数据库架构。
¥Calculates the target database schema as a function of the current Prisma schema.
-
比较现有迁移历史记录和目标架构的最终状态,并生成从一个迁移到另一个的步骤。
¥Compares the end state of the existing migration history and the target schema, and generates steps to get from one to the other.
-
将这些步骤渲染为 SQL 字符串并将其保存在新的迁移文件中。
¥Renders these steps to a SQL string and saves it in the new migration file.
-
评估 SQL 导致的数据丢失并触发警告。
¥Evaluate data loss caused by the SQL and warns about that.
-
将生成的迁移应用到开发数据库(假设你没有指定
--create-only
标志)¥Applies the generated migration to the development database (assuming you have not specified the
--create-only
flag) -
删除影子数据库(通过
shadowDatabaseUrl
配置的影子数据库不会被删除,而是在migrate dev
命令开始时重置)¥Drops the shadow database (shadow databases configured via
shadowDatabaseUrl
are not dropped, but are reset at the start of themigrate dev
command)
手动配置影子数据库
¥Manually configuring the shadow database
在某些情况下,手动定义应用作 migrate dev
影子数据库的数据库的连接字符串和名称可能是有意义的(例如,当 云托管数据库上不允许创建和删除数据库 时)。在这种情况下,你可以:
¥In some cases it might make sense (e.g. when creating and dropping databases is not allowed on cloud-hosted databases) to manually define the connection string and name of the database that should be used as the shadow database for migrate dev
. In such a case you can:
-
创建一个用作影子数据库的专用数据库
¥Create a dedicated database that should be used as the shadow database
-
将该数据库的连接字符串添加到环境变量
SHADOW_DATABASE_URL
(或.env
文件)¥Add the connection string of that database your environment variable
SHADOW_DATABASE_URL
(or.env
file) -
添加读取此环境变量的
shadowDatabaseUrl
字段:¥Add the
shadowDatabaseUrl
field reading this environment variable:
datasource db {
provider = "postgresql"
url = env("DATABASE_URL")
shadowDatabaseUrl = env("SHADOW_DATABASE_URL")
}
重要的:请勿对
url
和shadowDatabaseUrl
使用完全相同的值,因为这可能会删除数据库中的所有数据。¥Important: Do not use the exact same values for
url
andshadowDatabaseUrl
as that might delete all the data in your database.
云托管影子数据库必须手动创建
¥Cloud-hosted shadow databases must be created manually
某些云提供商不允许你使用 SQL 删除和创建数据库。有些需要通过在线界面创建或删除数据库,有些实际上限制你只能使用 1 个数据库。如果你在这样的云托管环境中进行开发,你必须:
¥Some cloud providers do not allow you to drop and create databases with SQL. Some require to create or drop the database via an online interface, and some really limit you to 1 database. If you develop in such a cloud-hosted environment, you must:
-
创建专用的云托管影子数据库
¥Create a dedicated cloud-hosted shadow database
-
将 URL 添加到环境变量
SHADOW_DATABASE_URL
¥Add the URL to your environment variable
SHADOW_DATABASE_URL
-
添加读取此环境变量的
shadowDatabaseUrl
字段:¥Add the
shadowDatabaseUrl
field reading this environment variable:
datasource db {
provider = "postgresql"
url = env("DATABASE_URL")
shadowDatabaseUrl = env("SHADOW_DATABASE_URL")
}
重要的:请勿对
url
和shadowDatabaseUrl
使用相同的值。¥Important: Do not use the same values for
url
andshadowDatabaseUrl
.
影子数据库用户权限
¥Shadow database user permissions
为了在使用 migrate dev
时创建和删除影子数据库,Prisma Migrate 目前要求 datasource
中定义的数据库用户具有创建数据库的权限。
¥In order to create and delete the shadow database when using migrate dev
, Prisma Migrate currently requires that the database user defined in your datasource
has permission to create databases.
数据库 | 数据库用户要求 |
---|---|
SQLite | 无特殊要求。 |
MySQL/MariaDB | 数据库用户必须具有 CREATE, ALTER, DROP, REFERENCES ON *.* 权限 |
PostgreSQL | 用户必须是超级用户或具有 CREATEDB 权限。参见 CREATE ROLE (PostgreSQL 官方文档) |
微软 SQL 服务器 | 用户必须是站点管理员或具有 SERVER 安全权限。参见 官方文档。 |
如果你使用云托管数据库进行开发并且无法使用这些权限,请参阅:云托管影子数据库
¥If you use a cloud-hosted database for development and can not use these permissions, see: Cloud-hosted shadow databases
注意:例如,在 Azure SQL 上禁用自动创建影子数据库。
¥Note: The automatic creation of shadow databases is disabled on Azure SQL for example.
如果 Prisma Migrate 无法使用你的连接 URL 提供的凭据创建影子数据库,则会引发以下错误:
¥Prisma Migrate throws the following error if it cannot create the shadow database with the credentials your connection URL supplied:
Error: A migration failed when applied to the shadow database
Database error: Error querying the database: db error: ERROR: permission denied to create database
要解决此错误:
¥To resolve this error:
-
如果你在本地工作,我们建议你更新数据库用户的权限。
¥If you are working locally, we recommend that you update the database user's privileges.
-
如果你正在针对不允许创建和删除数据库(出于任何原因)的数据库进行开发,请参阅 手动配置影子数据库
¥If you are developing against a database that does not allow creating and dropping databases (for any reason) see Manually configuring the shadow database
-
如果你正在针对基于云的数据库(例如,在 Heroku、Digital Ocean 或 Vercel Postgres 上)进行开发,请参阅:云托管影子数据库。
¥If you are developing against a cloud-based database (for example, on Heroku, Digital Ocean, or Vercel Postgres) see: Cloud-hosted shadow databases.
-
如果你正在针对基于云的数据库(例如,在 Heroku、Digital Ocean 或 Vercel Postgres 上)进行开发,并且当前正在进行原型设计,因此你不关心生成的迁移文件,而只需将 Prisma 架构应用到数据库 schema,你可以运行
prisma db push
而不是prisma migrate dev
命令。¥If you are developing against a cloud-based database (for example, on Heroku, Digital Ocean, or Vercel Postgres) and are currently prototyping such that you don't care about generated migration files and only need to apply your Prisma schema to the database schema, you can run
prisma db push
instead of theprisma migrate dev
command.
重要的:仅在开发环境中需要影子数据库(特别是对于
prisma migrate dev
命令) - 你不需要对生产环境进行任何更改。¥Important: The shadow database is only required in a development environment (specifically for the
prisma migrate dev
command) - you do not need to make any changes to your production environment.