关于迁移历史
本页解释了 Prisma ORM 如何使用迁移历史来跟踪您 schema 的更改。
迁移历史
您的迁移历史记录了您的数据模型的更改故事,并由以下内容表示:
-
一个
prisma/migrations
文件夹,其中包含子文件夹,以及每个迁移的migration.sql
文件migrations/
└─ 20210313140442_init/
└─ migration.sql
└─ 20210313140442_added_job_title/
└─ migration.sqlmigrations
文件夹是您的数据模型历史记录的事实来源。 -
数据库中的一个
_prisma_migrations
表,用于检查- 是否已针对数据库运行迁移
- 是否已删除已应用的迁移
- 是否已更改已应用的迁移
如果您更改或删除迁移(不推荐),则后续步骤取决于您是在开发环境(因此使用
migrate dev
)还是生产/测试环境(因此使用migrate deploy
)。
不要编辑或删除已应用的迁移
一般来说,您不应编辑或删除已应用的迁移。这样做可能会导致开发和生产环境迁移历史记录之间的不一致,这可能会产生无法预见的后果——即使更改最初看起来没有破坏任何东西。
以下场景模拟了一个看似无害的不一致性更改
- 修改已应用在开发环境中的现有迁移,将
VARCHAR(550)
的值更改为VARCHAR(560)
./prisma/migrations/20210310143435_default_value/migrations.sql进行此更改后,迁移历史记录的最终状态不再与 Prisma schema 匹配,Prisma schema 仍然具有-- AlterTable
ALTER TABLE "Post" ALTER COLUMN "content" SET DATA TYPE VARCHAR(560);@db.VarChar(550)
。 - 运行
prisma migrate dev
- Prisma Migrate 检测到迁移已更改,并要求reset
数据库? The migration `20210310143435_change_type` was modified after it was applied.
We need to reset the PostgreSQL database "migrate-example" at "localhost:5432".
Do you want to continue? All data will be lost. » (y/N) - 如果您接受重置,Prisma Migrate 将重置数据库并重放所有迁移,包括您编辑的迁移。
- 应用所有现有迁移后,Prisma Migrate 会将迁移历史记录的最终状态与 Prisma schema 进行比较,并检测到差异
- Prisma schema 具有
@db.VarChar(550)
- 数据库 schema 具有
VARCHAR(560)
- Prisma schema 具有
- Prisma Migrate 生成一个新的迁移,将值改回
550
,因为迁移历史记录的最终状态应与 Prisma schema 匹配。 - 从现在开始,当您使用
prisma migrate deploy
将迁移部署到生产和测试环境时,Prisma Migrate 始终会警告您迁移历史记录不匹配(并且每次运行命令时都会继续警告您) - 即使 schema 的最终状态匹配6 migrations found in prisma/migrations
WARNING The following migrations have been modified since they were applied:
20210310143435_change_type
在 migrate reset
之后,一个看起来没有破坏任何东西的更改可能会隐藏问题 - 您最终可能会在生产环境中遇到一个在开发环境中无法复现的错误,或者反之亦然 - 特别是当更改涉及到高度自定义的迁移时。
如果 Prisma Migrate 报告缺少或编辑了已应用的迁移,我们建议修复根本原因(恢复文件或还原更改),而不是重置。
在某些情况下,手动更改您的迁移历史记录实际上不会更改数据库 schema,例如向生成的 SQL 迁移添加注释。在这些情况下,您可以按照此教程中的说明来避免重置数据库。
将迁移历史记录提交到源代码控制
您必须将整个 prisma/migrations
文件夹提交到源代码控制。这包括 prisma/migrations/migration_lock.toml
文件,该文件用于检测您是否尝试更改 providers。
仅对 schema.prisma
文件进行源代码控制是不够的 - 您必须包含您的迁移历史记录。这是因为
- 当您开始自定义迁移时,您的迁移历史记录包含无法在 Prisma schema 中表示的信息。例如,您可以自定义迁移以减轻由破坏性更改引起的数据丢失。
prisma migrate deploy
命令用于将更改部署到暂存、测试和生产环境,仅运行迁移文件。它不使用 Prisma schema 来获取模型。