Visual Studio 个数据库项目中的版本更新

Versioning updates in Visual Studio database projects

我的公司使用 Visual Studio 数据库项目将更新部署到我们的数据库。据我所知,它提供了比较项目模式和目标数据库的状态,并生成代码以将后者的模式更新为前者的功能。它还提供了一个预部署脚本和一个 post-部署脚本,但仅此而已。

这里缺少的是版本控制 and/or 排序的任何概念。例如,如果我想将一个不可为空的 FK 列添加到 table,我需要分两步完成 - 首先,使用 post-deploy 脚本将其添加为可空列更新行以在其中具有有意义的值。其次,使列不可为空。这些必须按顺序发生。

据我所知,在使用 Visual Studio 数据库项目进行部署时,无法确保预部署脚本和 post 部署脚本的顺序排序。我在这里吗?这有两个含义:首先,一旦 table 创建后,您就不能真正将不可空的 FK 列添加到它,其次,您的预部署和 post- 部署脚本是将继续增长和增长,并包含多年前的垃圾,因为它们都是运行 每次 部署数据库。

有没有办法对 Visual Studio 数据库项目进行版本更新,如果没有,是否有允许这种版本控制的项目类型?

首先,您将此标记为 visual studio 2012 - 如果您使用的是该版本,请务必升级到 vs 2013 或 2015 并获取最新版本的 SSDT,因为每 3 个月发布一次新功能和修复,因此非常值得获得更新版本 - 我在下面谈论的是当前行为,我不知道所有这些是否在 visual studio 2012 的原始 ssdt 中可用。

有几件事要说,首先,您可以通过使用 /p:BlockWhenDriftDetected 并结合将数据库注册为数据层应用程序 (/p:RegisterDataTierApplication) 来强制执行有序部署。这将允许您这样做:

  1. 构建 dacpac 1
  2. 部署 dacpac 1
  3. 构建 dacpac 2
  4. 部署 dacpac 2
  5. 构建 dacpac 3

这会阻止您在部署 dacpac 1 之前部署 dacpac 2,但这并不理想,因为如果您在部署 dacpac 2 之前构建了 dacpac 3,那么您将无法在不重建 dacpac 3 的情况下进行部署,所以这并不理想。

当您处理数据库(任何 rdbms 而不仅仅是 sql 服务器)的更改时,有时我们需要分阶段发布更改,对我而言,这更多的是流程问题而不是技术问题一。我做的是:

  1. 创建更改的第一部分
  2. 在积压工作中创建工单以完成更改
  3. 部署更改
  4. 在部署后的未来迭代中,拿起票以完成更改
  5. 部署完成

关于此的一些注意事项:

  • 需要纪律来确保你整理和完成东西,以敏捷的方式工作并不意味着草率:)
  • 您编写的任何脚本都应该是幂等的,因此如果您想设置一些静态数据等,请使用类似 if exists 检查或合并语句的东西,如果您修改任何模式对象,则将它们包装在 if exists 等中。如果您这样做,您会发现部署体验要简单得多

如果您遵循此过程而不是依赖版本控制类型的策略,那么您不必担心部署 dacpacs 的顺序,如果脚本很重要,请将其留在 post 部署脚本中并在执行之前检查脚本是否应该做任何工作。如果您的脚本变得太大,您可以使用 :r sqlcmd 导入将它们分成不同的文件。我还听说有人使用部署存储过程并从 post-部署脚本中调用它们。

我更喜欢只部署最新(或特定版本)dacpac 的过程,因为这意味着无论您是要进行更高版本还是回退到更早版本,您始终可以部署到该版本.

最后,对于添加不可为 null 的 fk 列的示例,可以通过单次部署 dacpac 来完成此操作。为此,您需要:

  1. 创建新的 table 定义(包括非空和外键约束)
  2. 在您的 post 部署脚本中对 table 进行更新,以便正确设置数据(显然使其幂等,以便在需要时可以永久保留)
  3. 部署时启用/p:GenerateSmartDefaults

生成部署脚本后会发生什么,您会得到一个如下所示的脚本:

  • 预部署脚本(如果有)
  • 使用临时默认约束创建非空列
  • 删除临时约束
  • 使用 nocheck 创建外键,因此它实际上并没有被强制执行
  • 运行 post-部署脚本
  • 启用外键约束使用"with check check"

我提到的 /p: 参数是你传递给 sqlpackage.exe 的参数。如果您不使用它,而是使用其他方式进行部署,您通常可以将这些作为参数传递,如果您让我知道您在遇到困难时如何部署,我可以帮助您。有关参数的说明,请参阅 https://msdn.microsoft.com/en-us/library/hh550080.aspx(sqlpackage.exe 命令行语法)。

如果您有任何问题,请告诉我,还有一些其他事情需要考虑,但是检查您的架构定义并自动生成部署脚本可以显着减少部署更改的工作,这意味着您可以专注于更多事情有用 - 为一个编写单元测试 :).

埃德