【问题标题】:Dynamic database reference in SSDT (dacpac) projectSSDT (dacpac) 项目中的动态数据库引用
【发布时间】:2017-10-31 09:19:41
【问题描述】:

有没有一种方法可以在运行时派生 SQL Server 数据库项目 (Dacpac) 中的数据库引用?

我们正在构建一个使用 Dacpac 部署数据库对象的产品。

我们的产品实施团队还通过将数据库引用添加到产品 Dacpac 文件,然后将他们自己的其他对象添加到项目中来使用 Dacpac 项目。

我们面临的问题是——每次实现需要指向较新的产品发布版本时,都必须手动更改实现 dacpac 中的父 dacpac 引用以引用新产品 dacpac 的新文件路径(在较新的版本中)。我们在每个实施中都有多个实施团队和多个数据库项目。

有没有什么方法可以在运行时使用变量或参数或类似的东西导出数据库项目中的数据库引用 (*.dacpac)?

【问题讨论】:

  • 将 dacpacs 放到共享位置
  • 只是为了澄清一下 - 您的意思是当您部署项目时,您总是想要部署最新的 dacpac,或者当您构建实施项目时,您想要针对缺少一些位的 dacpac 构建(从旧版本)?
  • Dmitrij 的评论几乎就是我们要做的。构建适当版本的 dacpac,将其放在共享位置。必要时进行版本控制,并可能记下需要哪些构建以使一切正常工作。理想情况下,引用应该在一个公共路径中,如“..\..\..\Schema\DB1.dacpac”或类似的路径,因此对于所有项目来说都是相同的。
  • @EdElliott 我想让实施团队灵活地只在他们想要的时候进行升级。这意味着他们应该能够添加对任何产品 (dacpac) 发行版本的引用。目前,如果他们指向上个月的产品版本 1.0.1,而如果他们现在想指向本月的 1.0.2,他们将不得不手动更改所有 SQLproj 文件才能引用 1.0 .2 产品 dacpac。

标签: sql-server-data-tools database-project dacpac


【解决方案1】:

我对你的问题的理解如下:

您有一个 SSDT 数据库项目(参见下面的示例图),它有一个数据库引用(类似于下面的 #1),其中包含存储过程和访问参考数据库的其他 db 对象(类似于文件 #2 和代码 #3 )。您已经“构建”了导致 DACPac 的解决方案,现在您想要使用此 DACPac 并在部署时引用其他数据库。希望我正确理解了您的问题。

如果是这样,那么您可以使用发布配置文件功能来实现这一点(类似于下面的 #4)。

可以在我的 SSDT talk github project 的笔记中看到此代码。 如果您专门查看demo04 解决方案文件,您会看到我有一个DEV_MJE.deploy.ps1 PowerShell 文件和一个DEV_MJE2.deploy.ps1 文件。这些脚本运行 MSBuild 来构建 DACPac,然后使用 SqlPackage 分别发布 DEV_MJE.publish.xmlDEV_MJE2.publish.xml。请注意,如果您在计算机上运行此示例,则需要将 MSBuild.exeSqlPackage.exe 添加到您的路径中,并将 xml 文件中的 TargetConnectionString 修改为现有的开发数据库。

作为一个如何工作的示例...当我使用发布配置文件DEV_MJE.publish.xml 时,生成的 GetDataFromAnotherTable.sql 文件包含:

SELECT [SomeData] FROM [AnotherDb_MJE].[dbo].[AnotherTable]

而当我使用 DEV_MJE2.publish.xml 时,生成的 GetDataFromAnotherTable.sql 文件包含:

SELECT [SomeData] FROM [AnotherDb_MJE2].[dbo].[AnotherTable]

请注意,第二个中的数据库引用已更改为 AnotherDb_MJE2

有关发布配置文件如何与 DACPac 和 SSDT 数据库项目相关的详细说明,请参阅web page。它还包含有关在SqlPackage.exe 之外部署的替代方法的信息。

需要考虑的其他事项

请注意,使用文件路径对 DACPac 进行版本控制并不是最佳实践。将 DACPac 工件视为类似于 .Net DLL。它是构建的副产品。

因此,更好的方法是使用 NuGet 和 Octopus Deploy 等工具来存储、跟踪和部署 DACPacs。请参阅stackoverflow answer 了解其工作原理。

希望这会有所帮助,

迈克尔

【讨论】:

    【解决方案2】:

    感谢您的后续评论,我认为您正在尝试做的是当您编写和部署代码时能够根据项目使用不同的 dacpacs?​​

    每个实施团队可能部署了不同版本的共享 dacpac,因此您不能只是将文件放在共享位置并调用 dacpac“Product_Latest.dacpac”之类的东西,因此每个人都始终获得最新版本。

    “.sqlproj”文件是标准的 msbuild 脚本,可以使用 msbuild 属性管理引用,因此您可以在运行时从技术上更改引用。如果您编辑 .sqlproj 文件并在第一个 <PropertyGroup> 标记中添加一个属性,我使用:

    <ProdDacpacVersion Condition="'$(ProdDacpacVersion)' == ''">v1</ProdDacpacVersion>

    v1 是版本文件夹的唯一名称 - 你只需要一些东西来识别你想要的 dacpac。

    我将属性放在 TargetDatabaseSet 和 IncludeCompositeObjects 之后。

    如果您随后找到对 dacpac 的引用,而不是

    <ArtifactReference Include="..\..\..\..\..\Desktop\prod\v1\Database2.dacpac"> <HintPath>..\..\..\..\..\Desktop\prod\v1\Database2.dacpac</HintPath> <SuppressMissingDependenciesErrors>False</SuppressMissingDependenciesErrors> </ArtifactReference>

    使用上面的属性:

    <ArtifactReference Include="..\..\..\..\..\Desktop\prod\$(ProdDacpacVersion)\Database2.dacpac"> <HintPath>..\..\..\..\..\Desktop\prod\$(ProdDacpacVersion)\Database2.dacpac</HintPath> <SuppressMissingDependenciesErrors>False</SuppressMissingDependenciesErrors> </ArtifactReference>

    然后引用将使用该属性来获取 dacpac 的路径。有几种方法可以设置属性,当你想从文件或环境变量或其他东西中读取新版本的属性时,你可以编辑 .sqlproj 文件(我会把 msbuild 的乐趣留给你!) .

    作为标准,每次更改引用时,我都会重新加载项目或重新启动 Visual Studio - 这不会花费很长时间,并且会节省很多诅咒 :)

    部署 dacpac 时,部署首先会在同一个文件夹中查找引用,因此只需确保在部署时将正确的文件夹复制到 bin 文件夹中。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-06-09
      • 2020-10-13
      • 1970-01-01
      • 1970-01-01
      • 2017-12-26
      • 2021-12-01
      相关资源
      最近更新 更多