Skip to main content

压制迁移

本指南介绍如何将多个 迁移文件 压缩为单个迁移。

¥This guide describes how to squash multiple migration files into a single migration.

关于压缩迁移

¥About squashing migrations

有时将部分或全部迁移文件压缩为单个迁移很有用。本指南将描述你可能想要执行此操作的两种场景:

¥It is sometimes useful to squash either some or all migration files into a single migration. This guide will describe two scenarios where you may want to do this:

在这两种情况下,Prisma Migrate 都提供了执行此操作的工具,通过使用 migrate diff 命令比较两个数据库模式并输出一个 SQL 文件,将你从一个数据库模式转移到另一个数据库模式。本指南的其余部分详细说明了如何在这两种情况下执行此操作。

¥In both cases, Prisma Migrate provides the tools for doing this, by using the migrate diff command to compare two database schemas and output a single SQL file that takes you from one to the other. The rest of this guide gives detailed instructions on how to carry this out in these two scenarios.

从开发环境干净地迁移

¥Migrating cleanly from a development environment

使用基于分支的工作流程进行开发时,压缩迁移非常有用。在功能分支上进行大型本地开发工作期间,你可能会使用 migrate dev 生成多个迁移。该功能完成后,迁移历史记录可能包含不必要的中间步骤,这些步骤在将推送到 main 分支的最终迁移历史记录中是不需要的。

¥Squashing migrations can be useful when developing with a branch-based workflow. During a large local development effort on a feature branch you might generate multiple migrations using migrate dev. After the feature is finished, the migration history might contain unnecessary intermediate steps that are unwanted in the final migration history that will be pushed to the main branch.

避免在生产中应用中间步骤可能有重要原因 - 它们可能会丢失数据或速度极慢/具有破坏性)。即使情况并非如此,你也可能希望避免生产环境的迁移历史记录出现混乱。

¥There could be important reasons to avoid applying the intermediate steps in production — they might lose data or be extremely slow / disruptive). Even when this is not the case, you may want to avoid clutter in your production environment's migrations history.

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

¥For detailed steps on how to achieve this using migrate dev, see the section on how to migrate cleanly from a development environment.

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

¥Creating a clean history in a production environment

压缩迁移也可以在生产环境中使用,将所有迁移文件压缩为一个。当生产环境积累了较长的迁移历史记录并且由于中间步骤需要额外时间而在新环境中重放它已成为一种负担时,这可能很有用。由于团队没有从迁移步骤中获取价值(并且可以在紧要关头从版本控制历史记录中获取它们),因此决定将整个历史记录压缩为单个迁移。

¥Squashing migrations can also be used in a production environment to squash all migration files into one. This can be useful when the production environment has accumulated a longer migration history, and replaying it in new environments has become a burden due to intermediate steps requiring extra time. Since the team is not deriving value from the migration steps (and could get them back from version control history in a pinch) the decision is made to squash the whole history into a single migration.

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

¥For detailed steps on how to achieve this using migrate diff and migrate resolve see the section on how to create a clean history in a production environment.

压缩迁移时的注意事项

¥Considerations when squashing migrations

warning

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

¥When squashing migrations, be aware that any manually changed or added SQL in your migration.sql files will not be retained. If you have migration files with custom additions such as a view or a trigger, ensure to re-add them after your migrations were squashed.

如何抑制迁移

¥How to squash migrations

本节提供有关如何在上述两种情况下压缩迁移的分步说明:

¥This section provides step-by-step instructions on how to squash migrations in the two scenarios discussed above:

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

¥How to migrate cleanly from a development environment

在压缩迁移之前,请确保你具有以下起始条件:

¥Before squashing your migrations, make sure you have the following starting conditions:

  • 要压缩的迁移内容尚未应用于生产数据库

    ¥The contents of the migrations to be squashed are not yet applied on the production database

  • 所有应用于生产的迁移都已经成为本地迁移历史的一部分

    ¥All migrations applied to production are part of the local migration history already

  • 你添加到分支的任何新迁移文件中都没有自定义 SQL

    ¥There is no custom SQL in any of the new migration files that you have added to your branch

info

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

¥If the migration history on the production database has diverged after you created your feature branch, then you would need to first merge the migrations history and the datamodel changes from production into your local history.

然后按照下列步骤操作:

¥Then follow these steps:

  1. 重置本地 ./prisma/migrations 文件夹的内容以匹配 main 分支上的迁移历史记录

    ¥Reset the contents of your local ./prisma/migrations folder to match the migration history on the main branch

  2. 创建新的迁移:

    ¥Create a new migration:

    npx prisma migrate dev --name squashed_migrations

    这将创建一个单一迁移,让你:

    ¥This creates a single migration that takes you:

    • main 分支的状态(如重置迁移历史记录中所述)

      ¥from the state of the main branch as described in your reset migration history

    • ./prisma/schema.prisma 文件中描述的本地功能的状态

      ¥to the state of your local feature as described in your ./prisma/schema.prisma file

    • 并将其输出到以 squashed_migrations 结尾的新目录中的新 migration.sql 文件(用 --name 标志指定)

      ¥and outputs this to a new migration.sql file in a new directory ending with squashed_migrations (specified with the --name flag)

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

¥This single migration file can now be applied to production using migrate deploy.

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

¥How to create a clean history in a production environment

在压缩迁移之前,请确保你具有以下起始条件:

¥Before squashing your migrations, make sure you have the following starting conditions:

  • 迁移历史中的所有迁移都应用于生产数据库

    ¥All migrations in the migration history are applied on the production database

  • 数据模型与迁移历史匹配

    ¥The datamodel matches the migration history

  • 数据模型和迁移历史同步

    ¥The datamodel and the migration history are in sync

然后按照以下步骤操作,无论是在 main 分支上还是在新签出的分支上(在其他任何更改之前合并回 main 的分支上):

¥Then follow these steps, either on your main branch or on a newly checked out branch that gets merged back to main before anything else changes there:

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

    ¥Delete all contents of the ./prisma/migrations directory

  2. ./prisma/migrations 目录中创建一个新的空目录。在本指南中,这将被称为 000000000000_squashed_migrations。在其中添加一个新的空 migration.sql 文件。

    ¥Create a new empty directory in the ./prisma/migrations directory. In this guide this will be called 000000000000_squashed_migrations. Inside this, add a new empty migration.sql file.

    info

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

    ¥We name the migration 000000000000_squashed_migrations with all the leading zeroes because we want it to be the first migration in the migrations directory. Migrate runs the migrations in the directory in lexicographic (alphabetical) order. This is why it generates migrations with the date and time as a prefix when you use migrate dev. You can give the migration another name, as long as it it sorts lower than later migrations, for example 0_squashed or 202207180000_squashed.

  3. 创建一个单一迁移,让你:

    ¥Create a single migration that takes you:

    • 从空数据库

      ¥from an empty database

    • 生产数据库模式的当前状态,如 ./prisma/schema.prisma 文件中所述

      ¥to the current state of the production database schema as described in your ./prisma/schema.prisma file

    • 并将其输出到上面创建的 migration.sql 文件

      ¥and outputs this to the migration.sql file created above

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

    ¥You can do this using the migrate diff command. From the root directory of your project, run the following command:

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

    ¥Mark this migration as having been applied on production, to prevent it from being run there:

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

    ¥You can do this using the migrate resolve command to mark the migration in the 000000000000_squashed_migrations directory as already applied:

    npx prisma migrate resolve \
    --applied 000000000000_squashed_migrations

你现在应该有一个标记为已应用于生产的迁移文件。新的签出仅进行一次迁移,将它们带到生产数据库模式的状态。

¥You should now have a single migration file that is marked as having been applied on production. New checkouts only get one single migration taking them to the state of the production database schema.

生产数据库仍包含迁移表中应用的迁移的历史记录。迁移文件夹和数据模型的历史记录在源代码管理中仍然可用。

¥The production database still contains the history of applied migrations in the migrations table. The history of the migrations folder and data models is also still available in source control.