Mat*_*att 8 sql-server deployment data-tier-application
当我在 SSDT 数据库项目中包含登录名和用户并尝试使用“数据库偏离注册版本时阻止发布”选项部署 DACPAC 时,即使没有任何更改,它也始终会检测到数据库用户的漂移。
例如,我将项目发布到以前不存在数据库的新服务器上,并且一切正常。正确创建了登录名和用户等。然后我立即将同一个项目发布到同一个服务器上,部署被阻止,因为 db 用户已经漂移。但是我没有对 SQL 实例进行任何更改,甚至没有更新项目。
如果我从 SSDT 项目中删除登录名和用户,那么一切都会按预期进行,即我不会从漂移检测中得到误报,并且我可以更新和部署其他类型的对象而不会出错。
这是登录和用户的脚本:
CREATE LOGIN AppAcct WITH PASSWORD = 'Password1';
GO
CREATE USER AppAcct FOR LOGIN AppAcct
WITH DEFAULT_SCHEMA = dbo;
GO
GRANT CONNECT TO AppAcct;
GO
Run Code Online (Sandbox Code Playgroud)
这是我正在使用的发布配置文件:
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<IncludeCompositeObjects>True</IncludeCompositeObjects>
<TargetDatabaseName>DacpacDrift</TargetDatabaseName>
<DeployScriptFileName>DacpacDrift.sql</DeployScriptFileName>
<TargetConnectionString>Data Source=.\dev14;Integrated Security=True;Pooling=False</TargetConnectionString>
<BlockWhenDriftDetected>True</BlockWhenDriftDetected>
<RegisterDataTierApplication>True</RegisterDataTierApplication>
<ProfileVersionNumber>1</ProfileVersionNumber>
<ScriptDatabaseOptions>True</ScriptDatabaseOptions>
<BlockOnPossibleDataLoss>True</BlockOnPossibleDataLoss>
<DropObjectsNotInSource>True</DropObjectsNotInSource>
</PropertyGroup>
</Project>
Run Code Online (Sandbox Code Playgroud)
这就是漂移报告的样子:
<?xml version="1.0" encoding="utf-8"?>
<DriftReport xmlns="http://schemas.microsoft.com/sqlserver/dac/DriftReport/2012/02">
<Additions />
<Removals />
<Modifications>
<Object Name="[AppAcct]" Parent="" Type="SqlUser" />
</Modifications>
</DriftReport>
Run Code Online (Sandbox Code Playgroud)
在这个例子中,我使用的是针对 SQL Server 2014 的 Visual Studio 2013,但我也有其他版本的 SQL Server 也有同样的问题。我直接从 Visual Studio 发布,如果这有区别的话。
这是我构建的一个人为示例,试图缩小问题的根本原因并使其易于重现。实际上,SQL 登录将具有固定的 SID 和散列密码,并且会有其他用户映射到域帐户。最终,我希望为不同的目标实例提供不同的安全性,但现在我决定让通用登录名和用户作为项目的一部分工作。
真正的目标是让漂移检测正常工作,因为我所处的环境可能存在数据库漂移。我可以在项目之外管理权限(或作为部署前或部署后脚本),但随后 DACPAC 部署也将其视为漂移。
我对数据层应用程序比较陌生,所以我很可能从根本上误解了 DACPAC 部署应该如何管理,但在我尝试将用户和登录名添加到 SSDT 数据库项目之前,这一切对我来说都很好。
我错过了什么?
更新
我尝试了@dbajonm 的建议,但这只能让我达到我想去的地方。
我从项目中删除了用户和登录名,并手动将它们添加到我的测试实例上的目标数据库中。最终,我想在部署后脚本中管理它们,但现在我只是想解决漂移问题。
我更新了我的发布配置文件,以便它忽略登录名和用户等。 经过一些试验和错误,我最终在我的配置文件中使用了这些新设置:
<ExcludeUsers>True</ExcludeUsers>
<ExcludeLogins>True</ExcludeLogins>
<IgnorePermissions>True</IgnorePermissions>
<IgnoreRoleMembership>True</IgnoreRoleMembership>
Run Code Online (Sandbox Code Playgroud)
现在,当我尝试发布时,它生成的脚本不会删除用户或其权限或角色成员资格。就目前而言,这很好,因为如果我实际部署该 DACPAC,我不会破坏任何权限。问题是发布仍然被阻止,因为那些在部署脚本中被忽略的用户仍然被检测为数据库漂移。
所以这里是我的问题的根源,简而言之:
似乎无论我做什么,部署总是会因为数据库漂移而被阻止。这可能是对的吗? 真的没有办法可靠地检测包含数据库用户(即几乎所有用户)的数据库的漂移吗?
我知道无论如何我都可以忽略漂移并发布,但这使得漂移检测或多或少对我的目的毫无用处。我试图引导我们的团队远离直接针对数据库进行开发,而是将数据库代码视为值得进行版本控制等的一等公民。在过渡期间,我们将让人们在 SSDT 之外进行数据库更改项目,这就是为什么漂移检测对我来说如此重要。如果我总是从漂移检测中得到误报,那么它就会变得比它的价值更麻烦。
小智 2
要处理 DACPAC 外部的用户和登录,请设置以下选项。这可以在发布配置文件或您的项目设置中(因此您的两个场景)。
从 VS:项目属性 > 调试 > 高级... > 忽略 > 排除的对象类型。然后检查“排除登录”、“排除用户”、数据库角色等。发布/部署进行比较时您想要排除的任何内容。
从您的发布配置文件中,使用以下内容
<ExcludeUsers>True</ExcludeUsers>
<ExcludeLogins>True</ExcludeLogins>
Run Code Online (Sandbox Code Playgroud)
此排除选项隐藏在设置中。然而,这个选项直到 2014 年才可用,并让本地 SQL 数据库咬牙切齿!至少我们现在拥有了!
在 Visual Studio 和构建服务器上保持 SSDT 的最新状态势在必行!
| 归档时间: |
|
| 查看次数: |
10523 次 |
| 最近记录: |