1

问题:如何处理具有缓慢提交/gerrit 的顺序数据库迁移脚本。

设置如下:

  • 数据库表的持续开发是通过添加具有顺序名称的文件(12.sql、13.sql、14.sql 等)来完成的
  • 在数据库中设置了版本号
  • 迁移工具根据文件检查版本,以查看是否有未处理的数据库迁移

这种方法的主要问题(否则效果很好)是,当两个开发人员同时添加迁移脚本时,他们中的最后一个提交将发生合并冲突。在 subversion 中(我们一直使用到现在),这是一个树冲突,提交者通过还原该文件并使用新文件名添加它来处理,作为最后一个操作。由于我们在主干上使用了这些东西,他们通常会设法修复文件名作为最后的快速操作。

现在我们正在迁移到 git,冲突将改为在文件中显示为差异,这使得分离两个提交的文件(它们可能是不同提交包的一部分,以及其他文件)变得更加棘手。此外,由于我们使用 gerrit 进行代码审查,因此在将文件推送到主 git 存储库之间会有延迟,因此时不时会出现这种情况:

  1. 你推送一个迁移
  2. Gerrit 在代码审查后发生冲突
  3. 您通过重命名文件来解决冲突,并推送新的提交(必须重新审查)
  4. 在代码审查之前,有人设法进行了新的迁移,因此 Gerrit 再次发生冲突
  5. 您通过重命名文件来解决冲突,并推送新的提交(必须重新审查)
  6. 从 4 开始重复,直到你幸运并且 Gerrit 成功提交迁移。

解决这种情况的最佳方法是什么?

4

3 回答 3

4

我使用liquibase来管理我的数据库迁移。

它使用 XML 语法来描述数据库的每个“变更集”。虽然这可能是采用的障碍,但我发现它将来自不同开发人员的贡献合并到同一个文件中变得更加容易。

<changeSet id="bob-20130115-1" author="bob">
    <createTable tableName="commontable">
       ..
       ..
    </createTable>
</changeSet>

<changeSet id="tom-20130115-1" author="tom">
    <addColumn tableName="commontable">
        <column name="newcolumn" type="varchar(255)"/>
    </addColumn>
</changeSet>

使用 liquibase 的第二个优点是它支持回滚。如果发生冲突,我们可以撤消变更集,将我们带回上一个稳定版本,修复迁移文件并执行全新更新。

如果您没有切换工具的奢侈,那么我建议也许采用 liquibase 的方法,将 DEV 期间的每次迁移都视为“变更集”。每次迭代使用单个迁移文件,并在每个开发人员贡献的开始和结束处添加注释。在合并冲突的情况下,不要尝试重新编写 SQL,而是重新排序,以便一个开发人员的更改在其他人之前或之后。(强制其他开发人员创建另一个文件的方法是有效的,但我发现在实践中很难实施,因为第三个开发人员稍后出现并与序列中的下一个数字冲突......)

在没有回滚功能的情况下管理集成环境很棘手......除了每次都从头开始重建数据库之外,我不知道任何简单的方法。也许唯一有效的方法是听从 VonC 的建议,将数据库更改者的数量保持在最低限度。

笔记:

  • 每个使用自己的数据库的开发人员都是给定的。您正在使用迁移工具,因此应该没有异议。它简化了问题,尤其是当您需要消除和重建架构时。它还迫使您解决“测试数据”挑战....当我在一个测试数据位于单个数据库实例中的项目上工作时,我会努力工作....
  • 我最近发现SQL Alchemy migrate具有与 liquibase 相同的回滚功能。它强制您为每次迁移编写前滚和回滚脚本。
于 2013-01-15T20:12:21.133 回答
2

我将 Liquibase 作为一种解决方案。恕我直言,Mark O'Connor 没有很好地指出 Liquibase 的一个属性是,Liquibase 维护一个已应用变更集的列表,而不是您方法中最后应用的变更。

因此(只要更改标识符不冲突)分支不是问题。Liquibase 简单地应用所有尚未在 XML 中按顺序应用的未完成的变更集。作为检测冲突的功能,Liquibase 还存储了变更集源代码本身的 MD5 哈希,因此它也能够检测到变更“XY”本身的内容已更改。在这种情况下,您必须手动找出问题所在,并教导您的开发人员同事在任何第三方应用后不要更改任何变更集。

如果您不想切换/引入像 liquibase 这样的新数据库版本控制工具,我认为您可以轻松地将自定义方法扩展到这个方向。只需维护已应用更改的列表,只要您的文件名不匹配,您就可以很好地处理分支。

于 2013-01-16T15:17:42.443 回答
0

两个开发者同时添加一个迁移脚本

他们需要在自己的分支上进行修改,并触发对 Gerrit 的单独审查。
集成商(或两个开发人员之一)将负责合并和审查两个开发工作。

那,或者两者之间的通信需要改进,如果“dev 1”需要获得一些补丁(代表“dev 2”的工作)首先在“dev 1”的工作树中。

于 2013-01-15T13:51:51.893 回答