Symfony 4:如何安全地 'join' 一起迁移? / 删除第一个和最后一个之间的迁移?

Symfony 4: how to safely 'join' migrations together? / remove migrations in between the first and last?

我最近调整了我的数据库,注意到我在现有的 2 个迁移之上进行了 5 个迁移。所以总共 7 个,m1、m2、...、m7。从这 5 个中,我只想要最新版本。所以我想我可以删除 m3、m4、m5、m6、m7 并再次迁移,这将导致 m3 已经包含我满意的最终版本。现在我以前从未这样做过,想知道最安全的方法是什么?

我正在使用 PHPStorm。我可以手动删除它们吗(右键单击 PHPStorm 然后删除)然后转到命令行并执行 php bin/console doctrine:migrations:migrate?或者我需要做 php bin/console doctrine:schema:update 吗?或者这真的是个坏主意?

总的来说是可以的。 但是您应该知道 Doctrine/Migration 将已执行的迁移保存在 DB 中。所以你应该删除不必要的迁移文件(可能将所有查询合并为一个),然后更新数据库。

Table名称默认为“doctrine_migration_version”只是删除不需要的版本行

不,通常你不应该做其中任何一个。让我首先澄清一个看似错误的概念:迁移不包含完整的数据库模式,只包含将数据库从一个版本转移到下一个版本所需的查询。该系统允许对数据库更改进行管理和版本控制。所以你应该开始看到一些问题:

  • 一个迁移可能依赖于前一个迁移。例如。 v1 添加一个实体,v2 添加一个新字段。如果删除 v1,v2 将损坏,也需要删除。
  • 由于数据库迁移通常 与对象模型更改密切相关,因此您也必须恢复模型,否则您会发现不存在的映射问题字段。

当您还没有任何功能时,这可能是在设计阶段接受的table。您可以使用 bin/console doctrine:migrations:execute --down <version> 恢复单个迁移。如果需要进行调整,这通常是在测试更改时完成的。但通常是在尚未提交更改时。

Doctrine 使用名为 migration_versions 的数据库 table 跟踪迁移。通过用日期命名它们,它可以对它们进行排序并按顺序应用它们。每当执行迁移时,它都会将迁移名称添加到此 table。当你回滚它时,它会从 table 中删除它,连同迁移本身中的字段。请记住,即使您可以回滚迁移,但这并不意味着一切都会保持原样。如果迁移删除了一个列,该列将在回滚时重新创建,但数据将会丢失。

至于"can it be done"?是的。如果您真的想要,请仔细阅读 documentation 并了解所有这些内容。

因此,既然您的问题是关于合并迁移,那么让我们来解决您的实际选择:

  • 我可以手动删除它们吗(在 PHPStorm 中右键单击然后删除)然后转到命令行并执行 php bin/console doctrine:migrations:migrate

不,这行不通。 migrate 应用可用的 迁移。它们不会有任何变化,正如所解释的那样,修订仍将在 table 中并应用其更改。

  • 或者我需要做 php bin/console doctrine:schema:update

这也不会做任何事情,因为它将模型与数据库进行比较并发现它们匹配。

在任何情况下,您都需要先还原它们,然后再创建一个等效的。该命令是 doctrine:migrations:diff。这会将模型与架构进行比较并生成迁移以使数据库同步。为此,您需要先 execute --down 进行迁移,否则它们不会有任何变化,但可能会在此过程中丢失一些数据。

如果您在团队中工作,他们会看到迁移消失。有些甚至可能落后于历史并且没有应用 所有 迁移。这很快就会成为管理的痛点。 有一个 rollup 命令(根据我的理解并且从未实际使用过它)从 table 清除陈旧的迁移,转储完整的模式并应用它。这将是您最好的选择,但请注意,这最可能会删除您的数据。

您也可以手动合并迁移。它们只是 类 和 updown 方法。合并所有函数体,应用清理过程并收工。

现在,如果您想这样做,应该不是什么大问题。只需将过时的版本替换为新版本并警告所有人即可。但是,如果你想要做的是他们根本不存在并保持整洁的提交历史,那么你的队友可能会想杀了你,因为这将涉及 rewriting history。当你这样做时,他们将不得不重新调整他们所有的工作。

如果你想做:

  • 进行备份
  • 尽早介绍您的更改以避免中断。如果数据库中有一些未使用的字段一段时间是可以的,直到模型提交赶上。如果你做得太晚并且某些对象需要它,有人可能会被迫创建迁移并在此过程中破坏你的迁移。
  • 做对(最好是第一次尝试)。在您进行广泛测试之前不要强推。
  • 进行备份

参考 console commands

没有 "safe" 方法可以做到这一点,但如果您还没有部署迁移,那么您可以安全地丢弃一系列 auto-generated 迁移并重新生成它们。请注意不要同时丢弃手动迁移 SQL。

通常在设计阶段我们会:

  1. 使用doctrine:schema:update --force直到情况相当稳定
  2. 稳定后,我们从快照重置开发数据库
  3. 运行 doctrine:migrations:diff 然后在必要时添加手动迁移查询

您可能需要忽略所有迁移并专注于数据库模式的最后状态。如果这是你想在决赛中拥有的东西,那么你可以点击: php bin/console doctrine:schema:update --dump-sql 获取相应的 SQL 语句,或点击 php bin/console doctrine:schema:update --force 将其实际应用于数据库。