2012-08-27 25 views
1

我已经看过了所有的选项上.NET Migrations Engine,发现使用的Rails风格的迁移引擎是最有趣的,主要是因为他们都写在一个数据库无关这种方式可以轻松应对不同的数据库平台。.NET的Rails风格的数据库迁移与功能分支

但是,我看到了一个突出的问题是他们都不来解决开箱:源代码控制分支。

场景

  1. 特征1上正在BRANCH1开发和添加一列到名为COLUMN1
  2. 特征2表上正在BRANCH2开发和添加一列以命名COLUMN2
  3. 相同的表
  4. 推出1.1由包括特征2,但特征1尚未完成
  5. 特征1完成并合并到主干
  6. 推出1.2制成,然而新的列1 FIEL d是走进了树干在版本1(绑在代码中直接释放1.1),因此不会在数据库中,当它被迁移

工具,如Migrator.NET得到更新,这个问题似乎是迁移版本与实际的软件版本相关,而不是SCC提交。但是,该属性必须添加到源代码管理中的代码中。我已经看到了使用日期而不是版本的例子,但这似乎并没有解决增量版本以外的问题。

与我发现的答案最接近的是Liquibase FAQ page,但是解决方案需要在.NET中使用Rails风格的框架进行代码更改(即使在Rik Migrations中,它的结构属性类似于liquibase更改日志文件):

Liquibase是否与分支机构合作?是的。由于每次更改都是独立的,所以在不同的 分支中进行的数据库更改将在下次运行Liquibase时运行。您 可能会碰到的语句运行的顺序有问题,但 你可以通过重新排序更改日志文件 很容易解决的问题。

什么是处理这个问题的典型方式?

如果这有什么差别,我使用Git源控制。注意我已经看到标题为Database migrations in a complex branching system的帖子,但它没有真正提供答案。

回答

1

我已经给了一些这方面的思想,这就是我来了这么远。我还没有确定迁移框架,但下面的方法假设使用属性如Migrator.NET。但是,这也可以适用于其他移民。

由于问题在于迁移过早版本化(在开发过程中而不是在发布过程中),所以我的第一个直觉就是想出一个工作流程,确保在发布之前迁移无法版本化。这可以通过构建脚本,单元测试和源代码控制来完成。以下是具体步骤:

  1. 创建单元测试时比它们是在CI过程
  2. 创建单元测试失败更改时由运行当前的数据库版本更高版本存在MigrationAttributes失败任何与CI过程中运行的当前数据库版本相等或更低的迁移
  3. 在CI构建之前添加一个步骤,该步骤定位从Migration类继承的所有类,并添加版本为1的MigrationAttribute当前数据库版本。这确保迁移将在CI过程中成功运行。确保步骤1和2中的单元测试在此步骤之前运行。
  4. 在CI构建后添加一个步骤,将数据库表中的当前数据库版本设置回当前发布的数据库版本。我们的CI流程数据库版本只是暂时的。
  5. 在发布版本之前添加一个步骤,该步骤查找从Migration类继承的所有类,并添加版本高于当前数据库版本的MigrationAttribute。将此代码更改回到主干中。

这里的共同前提是,所有这一切都可以完全自动化,并且数据库迁移版本属性被添加既作为临时CI生成步骤和剥离步骤(由生成过程中,不手动地)。单元测试可确保在开发周期的早期编辑迁移或对其进行版本控制时不会发生作弊行为。

当然,步骤3和步骤4可以用CI过程中的删除/重新创建方法替换,它可能会更可靠。关键在于数据库版本化发生并在发布期间(以及从未)在源代码管理中检入。

版本控制

为了适应这种工作流程,我正在考虑让在上面的例子中AssemblyInformationalVersion属性

[assembly: AssemblyVersion("1.2.0.0")] 
[assembly: AssemblyFileVersion("1.2.3.4")] 
[assembly: AssemblyInformationalVersion("1.2.3.4+<GitHash>-<DBVersion>")] 

这样的数据库版本中,数据库的版本之后插入大会。这将允许我使用常规的主版本/次版本+版本,还可以跟踪程序集中当前版本的数据库发布版本(以及Git中的头部提交)。然后发布过程可以相应地增加这个版本,所有的单元测试和其他步骤将随之而来。请注意AssemblyInvormationalVersion在Windows中显示为Product Version。

GitHash只是前7个字符,这通常足以使其独特。

摘要

由这是因为它需要不与数据库版本intefering因为源代码将不包含在任何数据库的版本属性分支可能是复杂带走主要的事情分支(如果他们这样做,构建将失败)。但是,分支机构将包含迁移数据库所需的信息,这确实是一个开发步骤,而不是发布步骤。

显然,单元测试和构建脚本需要反射,代码注入以及与源代码管理提供程序一起工作以确保遵循规则,但这一切都是可能的。

我没有在实践中测试过这个,但是如果我找不到另一个解决方案,这可能是我将要去的方向。