1

我有一个使用 .net 2015 mvc 5 应用程序的 sql server 数据库。我的数据库代码是使用 SSDT 项目进行源代码控制的。我正在使用 SqlPackage.exe 使用由 SSDT 项目构建过程创建的 .Decpac 文件将数据库部署到暂存环境。这是使用 VSTS build 的 powershell 任务完成的。这样,我可以以源代码控制的方式更改数据库架构。现在的问题是关于数据库的主数据插入。

我使用一个 sql 脚本文件,该文件具有作为部署后脚本执行的数据插入脚本。该文件也是源代码控制的。

问题是,最初我们准备了插入脚本以针对第一个版本的 sprint(以 sprint n 作为基础)。但是在下一个冲刺中,如果更新一些主数据,那么应该如何更新主数据插入:

  1. 在脚本文件的最后添加新的更新/插入查询?但在这种情况下,部署后脚本将由 CI 执行,它会尝试在后续构建中一次又一次地插入数据,如果我们在该数据库的主表中进行了一些架构更改,最终将失败。
  2. 更新数据插入脚本中的现有插入查询。在这种情况下,我们也遇到了麻烦,因为在构建后事件中,整个数据将被重新插入。
  3. 为每个脚本维护单独的数据插入脚本,并将脚本引用更新到 SSDT 的构建后事件的新文件。这种方法需要手动操作并且容易出错,因为开发人员必须记住这个过程。这种方法的另一个问题是,如果我们需要在分布式服务器场中再设置 1 个数据库服务器。多个数据插入脚本会抛出错误,因为 SSDT 具有最新的架构,并且它将创建一个具有相同架构的数据库。但是较旧的数据脚本具有先前模式的数据插入(在以后的 sprint 中更改的 sprint wise db 模式)

因此,任何人都可以建议人工操作较少但可以涵盖上述所有情况的最佳方法。

谢谢鲁彭德拉

4

3 回答 3

1

确保您的部署前和部署后脚本始终是幂等的。但是,您要实现这取决于您。脚本应该能够运行任意次数并始终产生正确的结果。因此,如果您的架构更改会影响部署脚本,那么更新脚本是更改的依赖项,并伴随它在源代码控制中。数据库的版本控制已经是 SSDT 的内置功能。在项目文件本身中,有一个版本节点。VSTS 中有大量版本控制构建任务,您也可以免费使用它来对其进行版本控制。当 SqlPackage.exe 在已设置数据库版本的情况下发布您的项目时,会更新 msdb.dbo.sysdac_instances 中的一条记录。这比尝试管理、更新等您自己的本地版本解决方案要容易得多。和你' 不要用与应用程序本身无关的表和其他对象来弄乱应用程序的数据库。我同意将 sprint 信息排除在外。在我们的项目中,我用构建号标记成功构建的源代码,这当然会在源代码中创建一个与特定构建链接的时间点标记。

于 2018-09-20T17:13:44.413 回答
0

我在大多数项目中所做的是创建MERGE脚本,每个表一个,填充“主”或“静态”数据。有诸如https://github.com/readyroll/generate-sql-merge之类的工具可用于帮助生成这些脚本。

这些是从部署后脚本调用的,而不是在构建后操作中调用的。我通常为项目创建一个(你只允许一个!)部署后脚本,然后使用:r语法包含所有单独的静态数据脚本。部署后脚本只是一个.sql具有“部署后”构建操作的文件,可以“手动”创建,也可以使用 SSDT 中的“添加新对象”对话框并选择脚本 -> 部署后脚本。

然后可以将这些文件(包括部署后脚本)与其他源文件一起进行版本控制;如果您对表定义进行了更改,需要更改merge填充数据的语句,那么这些更改可以一起提交。

构建 dacpac 时,将包含所有主数据,并且由于您使用merge而不是插入,因此可以保证在部署结束时表的内容将与源代码控制的内容相匹配,就像 SSDT /sqlpackage 保证表的结构与源代码控制中的定义结构相匹配。

我不清楚“冲刺”的概念是如何出现的,除非“冲刺”意味着“发布”;在这种情况下,在 sprint 结束时构建和发布的 dacpac 将包含所有更改,包括在 sprint 期间添加的结构和“主数据”。我认为将“冲刺”的概念远离源代码控制可能是明智的!

于 2017-06-15T09:24:40.580 回答
0

我建议使用 MERGE 语句而不是插入。这样,您就可以在 sprint 范围内避免重复插入。

接下来是如何区分不同冲刺的不同插入。我建议实施版本编号以将数据库与 sprint 同步。所以创建一个表 DbVersion(version int)。然后在部署后脚本中执行以下操作:

SET @version = SELECT ISNULL(MAX(version), 0) FROM DbVersion 
IF @version < 1
 --inserts/merge for sprint 1
IF @version < 2
 --inserts/merge for sprint 2
...
INSERT INTO DbVersion(@currentVersion)
于 2017-06-14T19:15:55.413 回答