【问题标题】:AutoDeploy SQL changes with TeamCity (alternative to Redgate?)使用 TeamCity 自动部署 SQL 更改(替代 Redgate?)
【发布时间】:2013-09-06 13:08:48
【问题描述】:

我正在使用 TeamCity 为我们的测试环境创建 .NET 应用程序(使用 SVN 源代码控制)的 CI 和自动部署,一切进展顺利。我正处于想要自动执行 db 脚本的阶段。我进行了一些搜索并阅读了几篇文章,例如http://www.troyhunt.com/2011/02/automated-database-releases-with.html(troyhunt 的博客非常宝贵!),许多人似乎都指向使用 RedGate 软件来管理和部署更改。我有点担心让新工具处理脚本生成,所以想知道是否还有其他公认的方法值得研究。

我们当前的解决方案设计标准包括一个包含数据库相关文件的项目,例如我们的 orm db。它还包含一系列文件夹,其中包含我们的更改脚本,如下所示。

MySolution
 > MySolution.Data
    > 3.0 Scripts
       * 01 - UpdateUserTable.sql
       * 02 - UpdateRoleTable.sql
    > 3.1 Scripts
       * 01 - CreateJobTable.sql
       * 02 - InsertJobTypes.sql
       * 03 - AndSoOn.sql

我相信这种结构很重要,因为虽然我们希望在签入时自动部署到我们的测试环境,但我们部署实际版本的频率要低得多,而且我不确定 RedGate 的比较工具是否可以处理有时发生的更改级别。这就是为什么我更愿意为脚本使用版本文件夹,然后在发布时增加次要版本以保持脚本版本整洁。

有了这个预先存在的结构,我倾向于保留它并添加一个 TeamCity 构建定义,它可以在成功部署时应用 db 脚本。我想我可以让 TeamCity 在预期的路径中识别新添加的 .sql 文件到 SVN,然后在服务器上执行这些文件,但也许我期待太多了。我过去曾使用 TFS 和 MSBUILD 以及自定义构建步骤实现过这种解决方案,但对 TeamCity 方式完全陌生。

是否已经有实现类似目标的过程?在我看来,这似乎是一个很正常的实现,我只是还没有弄清楚是怎么回事。还是 RedGate 解决方案是我们应该追求的标准?

【问题讨论】:

  • 你用的是什么ORM框架?
  • 我们通常使用实体框架

标签: .net sql-server svn teamcity


【解决方案1】:

我在 2 年前读过同样的 Troy Hunt 文章。这是一个启示,我很快让我们使用 SQL Source Control + SQL Compare + TC 启动并运行。这是一个很好的解决方案,但是有些事情并没有像我想要的那样工作。其中最主要的是 SQL 源代码控制不能(或不能)很好地处理分支/合并策略。此外,SQL 源代码控制是一个带外过程,需要开发人员培训、采用和了解其怪癖。它从未扎根。我们的团队最终放弃了 RedGate,转而采用 TeamCity 驱动的实体框架迁移,而且我们没有回头。

对于您的直接问题:我认为您在这里尝试做的事情是可能的,尽管我认为寻找新添加的 SQL 脚本不一定是 TeamCity 的工作。 Red Gate 和 Entity Framework 都识别数据库本身中最近部署的脚本/迁移,并在确定应该从哪里开始应用更改时引用它。您可以在数据库中存储一个类似的值 ('3.0'),或者作为 TC 构建参数,然后使用 powershell 遍历较新的文件夹并使用 sqlcmd 应用最新的脚本。

不过,您可能会考虑查看基于 EF 的迁移,尤其是在您采用代码优先模型的情况下。如果您有兴趣,我可以更新此答案以详细讨论我们如何做到这一点。

更新:

EF 代码优先迁移通过在迁移类中捕获一组离散的数据库架构更改来工作。这个类有一个Up 和一个Down 方法,可以应用/反转该特定批次的模式更改。这或多或少等同于 Ruby 和其他人的做法。

当您对实体模型进行更改(添加表、删除列、更改约束等)时,您可以通过在包管理器控制台中调用 Add-Migration <DescriptionOfSchemaChange> 创建一个新的迁移类。这将生成名为<timestamp>_<DescriptionOfSchemaChange>.cs 的新类。然后,您可以通过调用 Update-Database 在本地应用该迁移。实体框架为您管理细节,但您可以根据需要将任意 SQL 注入迁移步骤。 PluralSight 提供了涵盖这些概念的 great course

迁移由作为实体框架 NuGet 包的一部分部署的可执行文件 migrate.exe 管理。在 TeamCity 中,您可以使用 migrate.exe 对指定的数据库运行迁移。首先,您必须将migrate.exe local 复制到包含您的迁移类的程序集中。然后,您只需使用 DB 连接字符串作为参数对该程序集运行 migrate.exe。工作目录是迁移程序集的目录。

copy ..\..\packages\EntityFramework.5.0.0\tools\migrate.exe .

migrate.exe ASSEMBLY.dll /connectionString="CONNECTION_STRING" /connectionProviderName="System.Data.SqlClient"

【讨论】:

  • 我正在调查你提出的 powershell 路由。但我对您基于 EF 的迁移很好奇(我实际上对这种方法一无所知)。
  • EF Migration 解决方案(虽然听起来不错)并不能真正满足我们的需求,所以作为修补匠,我决定踏上旅程,为此制作我自己的定制解决方案。我会发布一个答案,甚至可能会写一篇关于它的博客。
  • 我们使用相同的方法,但最近(升级到 EF6 后)我们在 TC 迁移期间遇到了 OutOfMemory 错误。你遇到过吗?
【解决方案2】:

经过大量搜索和了解如何实现我的目标后,我决定继续编写自己的控制台应用程序来为我完成此任务。我将在这里列出基本步骤,稍后可能会更详细地充实它们。

DatabaseRevisionUpdater(控制台应用)

  1. 使用 SVNSharp,DatabaseRevisionUpdater 挂钩到我们的 SVN 服务器 并从指定的 SVN 修订范围将 SQL 脚本文件读入内存。
  2. 在 .NET 创建的 Transaction 中,应用程序会一一读取脚本文件。如果在运行这些脚本时遇到任何错误,事务将回滚并且应用程序退出并返回错误代码 -1。
  3. 目标数据库应包含一些新的日志记录表,这些表会在进行更新时写入。版本表跟踪进行了哪些修订,成功和失败。一个单独的表包含有关为此修订请求运行的每个脚本的信息(状态为成功、失败和已跳过)。
  4. 当进行未来更新时,数据库的版本将根据步骤 3 中的表确定。如果请求与任何先前成功的更新相交,则更新将不会继续,因为它假定它已被应用。 SVN Update Revision From 也可以从这些表中确定。

TeamCity 集成

  • 添加了 Runner 类型的构建步骤:命令行
  • 工作目录是构建服务器上包含我的控制台应用程序的目录
  • 运行:自定义脚本(不要使用带参数的可执行文件,因为它似乎无法处理包含双引号的参数,例如我的 dbConnectionString)
  • 自定义脚本:可执行文件后跟针对我的数据库的参数。参数包括 svnUsername、svnPassword、svnPath、databaseConnectionString,最重要的是 RevisionTo。我使用 %build.vcs.number.APP_ID% 来获取当前版本的修订号。

奖励使用 - 更新断开连接的数据库

这一切都适用于我们的测试环境,但我们的实时环境位于无法访问 svn 或互联网的隔离网络上(出于安全原因)。在我的控制台应用程序中,我使用了几种不同的模式。上面描述的模式是直接更新,这是一个多合一的解决方案。它通过查看其日志表来确定数据库的当前版本,它轮询 SVN 以获取所有更新,直到您指定的修订版,它针对目标数据库运行它们并相应地更新其日志表。对于我们的现场环境,我添加了几个额外的模式。导出和导入。

  • 导出用于从修订范围内的 SVN 获取脚本。然后将它们保存到 XML 文件中。它根本不关心目标数据库。
  • Import 用于导入 XML 数据文件并将其中的更新应用到目标数据库。它关心版本兼容性,但与SVN无关。

这基本上是我的解决方案。没有什么是开箱即用的,但它就像一个魅力。我可以让 TeamCity 与它很好地交互,并使用控制台输出详细描述该过程,使其尽可能透明。 TeamCity 在其构建日志中报告所有这些输出,并且根据我的返回码为 0 或其他内容,失败或成功。

作为一个为期一周的旅程,我决定写一篇小博文,详细说明我是如何到达这里的,以防其他人感兴趣:https://andrekriegler.wordpress.com/2013/09/12/auto-deploy-database/

【讨论】:

    【解决方案3】:

    在 Red Gate,我们目前正在开发我们所谓的“迁移 v2”。这是一种数据库部署技术,既使用模式比较方法,也允许用户指定自己的脚本,例如在数据移动的情况下。

    series of web pagesa GoogleGroup forum 可以更好地描述这一点。

    如果您对此功能有任何疑问,请告诉我。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-08-01
      • 2018-09-15
      • 1970-01-01
      • 1970-01-01
      • 2018-06-27
      • 2013-11-25
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多