跳至主要内容

关于迁移历史

本页解释了 Prisma ORM 如何使用迁移历史来跟踪模式的更改。

迁移历史

您的迁移历史记录了数据模型更改的过程,并以以下方式表示:

  • 一个 prisma/migrations 文件夹,其中包含每个迁移的子文件夹和 migration.sql 文件

    migrations/
    └─ 20210313140442_init/
    └─ migration.sql
    └─ 20210313140442_added_job_title/
    └─ migration.sql

    migrations 文件夹是数据模型历史记录的**唯一来源**。

  • 数据库中的 _prisma_migrations 表,用于检查

    • 是否已对数据库运行迁移
    • 是否已删除应用的迁移
    • 是否已更改应用的迁移

    如果您更改或删除迁移(**不**建议),则下一步取决于您是在开发环境(因此使用 migrate dev)还是在生产/测试环境(因此使用 migrate deploy)。

请勿编辑或删除已应用的迁移

通常,您**不应编辑或删除**已应用的迁移。这样做会导致开发和生产环境迁移历史之间出现不一致,这可能会产生意想不到的后果——即使更改最初看起来没有破坏任何内容。

以下场景模拟了一个创建看似无害的不一致性的更改

  1. 修改在开发环境中**已应用**的**现有迁移**,将 VARCHAR(550) 的值更改为 VARCHAR(560)

    ./prisma/migrations/20210310143435_default_value/migrations.sql
      -- AlterTable
    ALTER TABLE "Post" ALTER COLUMN "content" SET DATA TYPE VARCHAR(560);

    进行此更改后,迁移历史的最终状态将不再与 Prisma 模式匹配,后者仍然具有 @db.VarChar(550)

  2. 运行 prisma migrate dev - Prisma Migrate 检测到迁移已更改,并要求 重置 数据库

    ? 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)
  3. 如果您接受重置,Prisma Migrate 将重置数据库并重放所有迁移,包括您编辑的迁移。

  4. 应用所有现有迁移后,Prisma Migrate 会将迁移历史的最终状态与 Prisma 模式进行比较,并检测到差异

    • Prisma 模式具有 @db.VarChar(550)
    • 数据库模式具有 VARCHAR(560)
  5. Prisma Migrate 生成一个新的迁移以将值更改回 550,因为迁移历史的最终状态应与 Prisma 模式匹配。

  6. 从现在开始,当您使用 prisma migrate deploy 将迁移部署到生产和测试环境时,Prisma Migrate 将始终**警告您**迁移历史不匹配(并在每次运行命令时继续警告您)——即使模式的最终状态匹配

    6 migrations found in prisma/migrations
    WARNING The following migrations have been modified since they were applied:
    20210310143435_change_type

migrate reset 后看似没有破坏任何内容的更改可能会隐藏问题——您最终可能会在生产环境中遇到无法在开发环境中复制的错误,反之亦然——尤其是在更改涉及高度自定义的迁移时。

如果 Prisma Migrate 报告已应用的丢失或已编辑的迁移,我们建议修复**根本原因**(恢复文件或撤消更改),而不是重置。

将迁移历史提交到源代码控制

您必须将整个 prisma/migrations 文件夹提交到源代码控制。这包括 prisma/migrations/migration_lock.toml 文件,该文件用于检测您是否尝试更改提供程序

仅对 schema.prisma 文件进行源代码控制是不够的——您必须包含迁移历史。这是因为

  • 当您开始自定义迁移时,您的迁移历史包含**无法在 Prisma 模式中表示的信息**。例如,您可以自定义迁移以减轻破坏性更改可能导致的数据丢失。
  • prisma migrate deploy 命令用于将更改部署到暂存、测试和生产环境,它**仅**运行迁移文件。它不使用 Prisma 模式来获取模型。