跳到主要内容

合并迁移

本指南介绍了如何将多个迁移文件合并为一个单一的迁移。

关于合并迁移

有时将部分或全部迁移文件合并为单个迁移非常有用。本指南将描述两种你可能希望这样做的情况

在这两种情况下,Prisma Migrate 都提供了实现这一功能的工具,即使用 migrate diff 命令比较两个数据库 Schema 并输出一个能将一个 Schema 转换为另一个 Schema 的单一 SQL 文件。本指南的其余部分将详细说明在这两种情况下如何执行此操作。

从开发环境干净地迁移

使用基于分支的工作流进行开发时,合并迁移会非常有用。在功能分支上进行大量的本地开发工作时,你可能会使用 migrate dev 生成多个迁移。功能完成后,迁移历史记录可能包含不必要的中间步骤,这些步骤是你希望在最终推送到 main 分支的迁移历史记录中避免出现的。

可能有一些重要原因需要避免在生产环境中应用中间步骤——它们可能会导致数据丢失或速度极慢/具有破坏性。即使不是这种情况,你可能也希望避免生产环境的迁移历史记录中出现混乱。

有关如何使用 migrate dev 实现此目标的详细步骤,请参阅如何从开发环境干净地迁移部分。

在生产环境中创建干净的历史记录

合并迁移也可以在生产环境中使用,将所有迁移文件合并为一个。当生产环境积累了较长的迁移历史记录,并且由于中间步骤需要额外时间而导致在新环境中重放历史记录成为负担时,这会非常有用。由于团队不会从这些迁移步骤中获取价值(并且在需要时可以从版本控制历史记录中找回它们),因此决定将整个历史记录合并为一个迁移。

有关如何使用 migrate diffmigrate resolve 实现此目标的详细步骤,请参阅如何在生产环境中创建干净的历史记录部分。

合并迁移时的注意事项

警告

合并迁移时,请注意 migration.sql 文件中任何手动更改或添加的 SQL 都不会被保留。如果你的迁移文件包含自定义添加内容,例如视图或触发器,请确保在合并迁移后重新添加它们。

如何合并迁移

本节提供了关于如何在上面讨论的两种情况下合并迁移的分步说明

如何从开发环境干净地迁移

在合并迁移之前,请确保满足以下初始条件

  • 要合并的迁移内容尚未应用到生产数据库上
  • 所有已应用到生产环境的迁移都已经包含在本地迁移历史记录中
  • 你已添加到分支的任何新的迁移文件中都没有自定义 SQL
信息

如果你创建功能分支后,生产数据库上的迁移历史记录发生了分歧,则需要先将生产环境的迁移历史记录和数据模型更改合并到你的本地历史记录中。

然后按照以下步骤操作

  1. 将本地 ./prisma/migrations 文件夹的内容重置为与 main 分支上的迁移历史记录一致

  2. 创建一个新的迁移

    npx prisma migrate dev --name squashed_migrations

    这将创建一个单一的迁移,使你可以

    • 从重置后的迁移历史记录中描述的 main 分支状态
    • 转换为你的 ./prisma/schema.prisma 文件中描述的本地功能状态
    • 并将结果输出到一个新的目录中的 migration.sql 文件中,该目录名称以 squashed_migrations 结尾(由 --name 标志指定)

现在可以使用 migrate deploy 将这个单一的迁移文件应用到生产环境了。

如何在生产环境中创建干净的历史记录

在合并迁移之前,请确保满足以下初始条件

  • 迁移历史记录中的所有迁移都已应用到生产数据库上
  • 数据模型与迁移历史记录匹配
  • 数据模型和迁移历史记录同步

然后按照以下步骤操作,可以在 main 分支上进行,也可以在一个新检出的分支上进行,该分支需要在 main 分支发生其他任何更改之前合并回 main

  1. 删除 ./prisma/migrations 目录下的所有内容

  2. ./prisma/migrations 目录下创建一个新的空目录。在本指南中,该目录将命名为 000000000000_squashed_migrations。在此目录内,添加一个新的空 migration.sql 文件。

    信息

    我们将迁移命名为带有前导零的 000000000000_squashed_migrations,因为我们希望它是迁移目录中的第一个迁移。Migrate 以字典序(字母顺序)运行目录中的迁移。这就是为什么当你使用 migrate dev 时,它会生成以日期和时间作为前缀的迁移。你可以给迁移起另一个名字,只要它在排序时位于后续迁移之前,例如 0_squashed202207180000_squashed

  3. 创建一个单一的迁移,使你可以

    • 从一个空的数据库
    • 转换为你的 ./prisma/schema.prisma 文件中描述的生产数据库 Schema 的当前状态
    • 并将结果输出到上面创建的 migration.sql 文件中

    你可以使用 migrate diff 命令执行此操作。在项目根目录运行以下命令

    npx prisma migrate diff \
    --from-empty \
    --to-schema-datamodel ./prisma/schema.prisma \
    --script > ./prisma/migrations/000000000000_squashed_migrations/migration.sql
  4. 将此迁移标记为已在生产环境中应用,以防止它在那里运行

    你可以使用 migrate resolve 命令将 000000000000_squashed_migrations 目录中的迁移标记为已应用

    npx prisma migrate resolve \
    --applied 000000000000_squashed_migrations

现在你应该有一个已标记为在生产环境中应用的单一迁移文件。新的检出操作只会得到一个单一的迁移,将其带到生产数据库 Schema 的状态。

生产数据库在迁移表中仍然包含已应用的迁移历史记录。迁移文件夹和数据模型的历史记录也仍然可以在源代码控制中获取。