Database 使用git/gerrit在中迭代数据库迁移

Database 使用git/gerrit在中迭代数据库迁移,database,git,migration,gerrit,Database,Git,Migration,Gerrit,问题:如何处理具有缓慢提交/gerrit的顺序数据库迁移脚本 设置如下: 数据库表的持续开发是通过添加具有顺序名称的文件(12.sql、13.sql、14.sql等)来完成的 在数据库中设置了版本号 迁移工具根据文件检查版本,以查看是否存在未处理的数据库迁移 这种方法的主要问题(在其他情况下效果很好)是,当两个开发人员同时添加迁移脚本时,最后提交的开发人员将出现合并冲突。在subversion中(我们一直使用到现在),这是一个树冲突,提交者通过还原该文件并添加一个新文件名(作为最后一个操作)

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

设置如下:

  • 数据库表的持续开发是通过添加具有顺序名称的文件(12.sql、13.sql、14.sql等)来完成的
  • 在数据库中设置了版本号
  • 迁移工具根据文件检查版本,以查看是否存在未处理的数据库迁移
这种方法的主要问题(在其他情况下效果很好)是,当两个开发人员同时添加迁移脚本时,最后提交的开发人员将出现合并冲突。在subversion中(我们一直使用到现在),这是一个树冲突,提交者通过还原该文件并添加一个新文件名(作为最后一个操作)来处理该冲突。因为我们在trunk上使用这些东西,所以他们通常会设法修复文件名,作为最后的快速操作

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

  • 你推动了一次迁移
  • Gerrit在代码检查后遇到冲突
  • 您可以通过重命名文件来修复冲突,并推送新的提交(必须重新审阅)
  • 在代码审查之前,有人设法进行了新的迁移,所以Gerrit再次遇到冲突
  • 您可以通过重命名文件来修复冲突,并推送新的提交(必须重新审阅)
  • 从4开始重复,直到您幸运且Gerrit成功提交迁移
  • 解决这种情况的最好办法是什么

    两个开发人员同时添加迁移脚本

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

    如果“dev 1”需要在“dev 1”的工作树中首先获得一些补丁(表示“dev 2”的工作),那么为了使“dev 1”在没有与“dev 2”进行检查的情况下不推送任何东西,或者说两者之间的通信需要改进

    两个开发人员同时添加迁移脚本

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

    如果“dev 1”需要在“dev 1”的工作树中首先获得一些补丁(代表“dev 2”的工作),那么这一点或两者之间的通信需要改进,以便“dev 1”在没有与“dev 2”进行检查的情况下不会推送任何东西

    它使用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相同的回滚功能。它强制您为每次迁移编写前滚和后滚脚本
    我用来管理数据库迁移

    它使用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相同的回滚功能。它强制您为每次迁移编写前滚和后滚脚本
    
    我将二次液化酶作为一种溶液。马克·奥康纳·伊姆霍(Mark O'Connor IMHO)没有很好地指出的Liquibase的一个特性是,Liquibase与你的方法中最后一次应用的变更相比,保持了一个应用变更集的列表

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


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

    I second Liquibase as one solution。马克·奥康纳·伊姆霍(Mark O'Connor IMHO)没有很好地指出的Liquibase的一个特性是,Liquibase与你的方法中最后一次应用的变更相比,保持了一个应用变更集的列表

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

    如果您不想切换/引入像liquibase这样的新数据库版本控制工具,我认为您可以