我正在使用TeamCity为我们的测试环境创建用于.NET应用程序的CI和自动部署(使用SVN控制的源代码),并且一切顺利。我正处于我想要自动执行db脚本的阶段。我已经做了一些搜索并阅读了几篇文章,例如http://www.troyhunt.com/2011/02/automated-database-releases-with.html(特洛伊特的博客非常宝贵!),许多人似乎都指出使用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在预期路径中向SVN识别新添加的.sql文件,然后在服务器上执行这些文件,但也许我开始期待开箱即用。我过去使用TFS和MSBUILD以及自定义构建步骤实现了这种解决方案,但对于TeamCity方式我是全新的。
是否已经有了实现这样的目标的过程?在我看来,这是一个非常正常的实现,我还没有找到如何。或者RedGate解决方案是我们应该采用的标准吗?
答案 0 :(得分:4)
我在2年前读过同样的特洛伊亨特文章。这是一个启示,我很快就开始使用SQL Source Control + SQL Compare + TC。这是一个很好的解决方案,但是有一些东西不能像我想的那样工作。其中最主要的是SQL Source Control不支持(或不支持)分支/合并策略。此外,SQL Source Control是一个带外过程,需要开发人员培训,采用和了解其怪癖。它从未扎根。我们的团队最终离开了RedGate,转而支持TeamCity驱动的Entity Framework迁移,我们没有回头。
直接提出问题:我认为你在这里尝试做的事情是可能的,尽管我认为寻找新添加的SQL脚本不一定是TeamCity的工作。红门和实体框架都识别数据库本身中最近部署的脚本/迁移,并在确定应该开始应用更改的位置时引用它。您可以在数据库中存储类似的值('3.0'),或者作为TC构建参数,然后使用powershell迭代较新的文件夹并使用 sqlcmd 应用最新的脚本。
您可能会考虑查看基于EF的迁移,特别是如果您采用了代码优先模型。如果您有兴趣,我可以更新此答案,以更多地谈论我们如何做到这一点。
<强>更新强>
EF代码优先迁移通过捕获迁移类中的一组离散数据库模式更改来工作。此类具有Up
和Down
方法,可以应用/反转特定批量的架构更改。这或多或少等同于Ruby和其他人的做法。
当您对实体模型进行更改(添加表,删除列,更改约束等)时,可以通过在程序包管理器控制台中调用Add-Migration <DescriptionOfSchemaChange>
来创建新的迁移类。这将生成名为<timestamp>_<DescriptionOfSchemaChange>.cs
的新类。然后,您可以通过调用Update-Database
在本地应用该迁移。实体框架为您管理细节,但您可以根据需要将任意SQL注入迁移步骤。 PluralSight提供了涵盖这些概念的great course。
迁移由可执行文件migrate.exe
管理,该可执行文件作为Entity Framework NuGet包的一部分进行部署。在TeamCity中,您可以使用migrate.exe
针对指定的数据库运行迁移。首先,您必须将migrate.exe
本地复制到包含迁移类的程序集。然后,您只需使用数据库连接字符串作为参数对该程序集运行migrate.exe
。工作目录是迁移程序集的目录。
copy ..\..\packages\EntityFramework.5.0.0\tools\migrate.exe .
migrate.exe ASSEMBLY.dll /connectionString="CONNECTION_STRING" /connectionProviderName="System.Data.SqlClient"
答案 1 :(得分:2)
经过大量搜索和了解我如何实现目标后,我决定继续编写我自己的控制台应用程序,为我做这个。我将在这里列出基本步骤,以后可以更详细地将它们充实。
DatabaseRevisionUpdater(控制台应用)
TeamCity Integration
奖金使用情况 - 更新已断开连接的数据库
这一切都适用于我们的测试环境,但我们的实时环境位于一个无法访问svn或互联网的隔离网络上(出于安全考虑)。使用我的控制台应用程序,我使用了一些不同的模式。上面描述的模式是直接更新,这是一个一体化的解决方案。它通过查看其日志表来确定DB当前版本,它会轮询SVN以查找所有更新,直到您指定的修订版本为止,它会针对目标数据库运行它们并相应地更新其日志记录表。对于我们的现场环境,我添加了几个额外的模式。出口和进口。
这基本上是我的解决方案。没有任何开箱即用,但它就像一个魅力。我可以很好地使TeamCity与它进行交互,并使用Console输出来详细描述使其尽可能透明的过程。 TeamCity在其构建日志中报告所有这些输出,也会失败或成功,具体取决于我的返回码是0或其他。
作为一个星期的旅程,我决定做一个小博客文章,详细说明我是如何到达这里以防其他人感兴趣的:https://andrekriegler.wordpress.com/2013/09/12/auto-deploy-database/
答案 2 :(得分:0)
在Red Gate,我们正在研究我们称之为“迁移v2”的内容。这是一种数据库部署技术,它既使用模式比较方法,也允许用户指定自己的脚本,例如在数据运动情况下。
有一个series of web pages可以更好地描述这一点,以及a GoogleGroup forum。
如果您对此功能有何疑问,请与我们联系。