这里有两个值得了解的想法。两者的灵感都来自我在 Ruby on Rails 中的背景,所以我包含了一些关于 Rails 如何在上下文中实现它的内容:
- 在 Rails 中,当您设置一个新数据库时,它并不期望每次都运行一次迁移,以获取正确的数据库。Rails 还维护一个名为的文件
schema.rb
,该文件保存数据库的当前、完整、最新状态(包括为达到该点而运行的迁移名称的列表)。因此,当您创建一个新数据库时,它只会读取schema.rb
文件中的任何内容并创建这些表。
然后,rails 将在该数据库上运行 FUTURE 迁移,继续前进。但是在创建最新版本之前已经运行的那些schema.rb
- 好吧,您根本不需要它们。事实上,一旦它们在需要的地方运行,您可以根据需要删除它们。
现在,sequelize 不这样做(尽管我希望它这样做!)。但是,您可以经常将整个数据库结构转储为 SQL。将其保存为例如。20170427051240-initial-structure.sql
,在您的迁移文件中,时间戳记为它包含的最新迁移之后的一秒。所以,现在你有了类似 Rail 的东西scehma.rb
。
下一步是:编辑直接在该时间戳之前运行的迁移,以便它所做的只是导入整个数据库结构。像这样的东西:
'use strict';
module.exports = {
up: function(queryInterface, Sequelize) {
if (!['test', 'ci'].includes(process.env.NODE_ENV)) {
// In all other environments, the database will already have been set up, so
// we don't need to import the full structure
return;
}
return queryInterface.sequelize.query(`
BIG FAT STRING OF SQL GOES HERE.
Note: in my app I've actually got it done table by table,
in separate chained promises, but don't remember why.
`)
}
}
好的。因此,现在您可以删除该迁移之前的所有迁移 - 因为无论如何该迁移都会处理之前运行的所有迁移。
有一些考虑,例如。你可能想保存20170427051240-initial-structure.sql
,然后等待一两个月,让另外 15 次迁移累积,然后执行上述步骤,这样设置一个新数据库就会像一个月前一样导入初始结构,在第一次迁移中,然后在此之上运行最近的 15 次迁移。这意味着您始终保留最后几次迁移的记录,以防您需要回滚它们或其他什么。
- Rails 世界中另一个更直接适用于上述问题的常见做法是将模型的副本保存在迁移文件中(即“及时冻结”的副本,可以这么说),并在您的迁移,而不是您的“真实”迁移,它可能会被删除。当然,您不必包含整个模型的完整副本以及所有方法等 - 您可以删除特定迁移不需要的任何内容。
这会使您的迁移文件变大而且有点混乱,但谁在乎呢?不编辑迁移。它们只运行一次,而且大部分都被遗忘了。因此,它们是否有点乱也没关系。
我还没有尝试过使用 sequelize 的第二种方法,但它对我来说在 Rails 中效果很好。
希望其中一些有用!