压制迁移
本指南介绍如何将多个 迁移文件 压缩为单个迁移。
¥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:
-
从开发环境干净地迁移 通过在合并之前将本地迁移压缩为一个
¥Migrating cleanly from a development environment by squashing your local migrations into one before merging
-
在生产环境中创建干净的历史记录 通过将所有迁移压缩到单个文件中
¥Creating a clean history in a production environment by squashing all migrations into a single file
在这两种情况下,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 diff
和 migrate 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
压缩迁移时,请注意,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
如果在创建功能分支后生产数据库上的迁移历史记录发生了分歧,那么你需要首先将迁移历史记录和数据模型更改从生产合并到本地历史记录中。
¥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:
-
重置本地
./prisma/migrations
文件夹的内容以匹配main
分支上的迁移历史记录¥Reset the contents of your local
./prisma/migrations
folder to match the migration history on themain
branch -
创建新的迁移:
¥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 withsquashed_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:
-
删除
./prisma/migrations
目录下所有内容¥Delete all contents of the
./prisma/migrations
directory -
在
./prisma/migrations
目录中创建一个新的空目录。在本指南中,这将被称为000000000000_squashed_migrations
。在其中添加一个新的空migration.sql
文件。¥Create a new empty directory in the
./prisma/migrations
directory. In this guide this will be called000000000000_squashed_migrations
. Inside this, add a new emptymigration.sql
file.info我们将迁移命名为
000000000000_squashed_migrations
,并带有所有前导零,因为我们希望它成为迁移目录中的第一个迁移。Migrate 按字典顺序(字母顺序)运行目录中的迁移。这就是为什么当你使用migrate dev
时它会生成以日期和时间作为前缀的迁移。你可以为迁移指定另一个名称,只要它的排序低于后来的迁移即可,例如0_squashed
或202207180000_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 usemigrate dev
. You can give the migration another name, as long as it it sorts lower than later migrations, for example0_squashed
or202207180000_squashed
. -
创建一个单一迁移,让你:
¥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 -
-
将此迁移标记为已应用于生产,以防止其在生产中运行:
¥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 the000000000000_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.