13

我正在做一些自动化操作,并且正在将一些 10-15 个旧的、古怪的脚本重写为一个简单的单元,它可以:

  1. 生产环境从MsSql2012导出数据库方案
  2. 开发环境导入数据库方案到MsSql2012

我使用Microsoft.SqlServer.Dac执行此操作,我可以在其中导出/导入 dac 包。

它工作得很好:),但是在完成了我所有的 TDD 和测试之后,是时候做真正的事情了,结果我完全错过了我们在工作中拥有 2 个域的情况。

这意味着当我在开发环境中导入 dacpac 时出现错误,因为我们的 2 个域没有完全的 2 路信任,当然数据库有来自这两个域的用户。特别是生产域用户。我可以看到 3 个可行的解决方案:

  1. 在环境之间获得完全信任。但这不会发生,因为我的工作实施了高水平的安全性。
  2. 导入没有用户的 dacpac。
  3. 在没有用户的情况下导出到 dacpac。

我已经阅读了文档(当然这是模糊的),试图找到一组可以实现 2)或 3)的选项。我测试了很多组合,但没有一个会起作用。dac pac 导入不断尝试创建用户并失败,因为无法在开发环境中验证生产用户。

我使用 Deploy 和 Extract 来导出/导入。可以在此处找到不同的选项:

  1. 提取:http ://technet.microsoft.com/en-us/library/microsoft.sqlserver.dac.dacextractoptions.aspx
  2. 部署:http ://technet.microsoft.com/en-us/library/microsoft.sqlserver.dac.dacdeployoptions.aspx

我没有找到有效的组合,我什至阅读了表明它是 DacPac 中的错误的帖子。但我不确定。我现在正在研究的最后一个选项是使用 GenerateScript 方法,该方法有望强制排除用户/登录名,但我担心它也不起作用。请参阅 ( http://technet.microsoft.com/en-us/library/hh753526.aspx )。

问题: 如何在导出或导入中从我的 dacpac 中排除用户/登录?

更新

当前提取设置:

IgnoreUserLoginMappings = true,
VerifyExtraction = false,

当前部署设置:

CreateNewDatabase = true,
DeployDatabaseInSingleUserMode = true,
DisableAndReenableDdlTriggers = true,
IgnoreUserSettingsObjects = true,

更新

到目前为止,一切都指向一个丑陋的解决方案。

I can generate a deploy script using DacServices. 
Then i can parse the script (Remove logins etc).
Then write the result to a file.
And then call SQLCMD in an external process given it the generated and parsed file. 
Finally i must evaluate the result from the SQLCMD process.

使用 SQLCMD 的原因是生成的脚本显然不是纯 tsql,而是使用 ':setvar' 的东西,据我所知,只有 SQLCMD 可以处理。来吧MS...

同样,如果有人知道在 C# 中执行此操作的更好方法,或者知道 DacPac 程序集的错误修复/更新,请分享。:)

更新

我发现 IgnorePartitionSchemes 之类的东西也不起作用。似乎命名空间 Microsoft.SqlServer.Dac 不仅有一点问题,而且非常有问题或缺乏实现。

4

4 回答 4

6

我设法通过以下dacpac文件部署解决了这个问题。重要的设置在ExcludeObjectTypes.

const string connectionString = @"Data Source=(LocalDB)\MSSQLLocalDB...";
var dacServices = new DacServices(connectionString);

// show deployment in the output window.
dacServices.Message += (o, args) => Debug.WriteLine(args.Message);
dacServices.ProgressChanged += (o, args) => Debug.WriteLine(args.Status);

// load the file.
var dacpac = DacPackage.Load("file.dacpac");
var options = new DacDeployOptions
    {
         IgnorePermissions = true,
         IgnoreUserSettingsObjects = true,
         IgnoreLoginSids = true,
         IgnoreRoleMembership = true,

         // THIS IS THE MAGIC SETTING THAT FINALLY WORKED.
         ExcludeObjectTypes = new[] { 
             ObjectType.Users,
             ObjectType.Logins,
             ObjectType.RoleMembership }
    };
dacServices.Deploy(
    dacpac,
    "MyDbName",
    true,
    options);
于 2016-07-06T15:02:17.603 回答
1

在部署期间,重要的设置是“IgnoreUserSettingsObjects”之一。这将忽略用户、用户-> 登录和用户-> 模式关系。将其设置为 true 应该是使其正常工作的主要内容。

在 Extract 上,您还可以将 DacExtractOptions.IgnoreUserLoginMappings 设置为 true。在这种情况下,用户->登录映射不包括在内,但看起来在部署时忽略用户更为重要。这确实意味着您需要在部署后运行脚本以确保存在正确的用户。

于 2014-02-20T21:17:15.007 回答
1

我正在努力解决类似的问题。DACPAC 只是一个 zip 存档,其中包含 3 个 XML 文件。我找到了一个dacpac 操作工具的源代码,并对其进行了修改,以从 DACPAC 中删除用户和登录。

于 2014-02-25T14:22:34.773 回答
0

The way we handled this was to simply exclude the tables which contained sensitive security information, then re-insert them afterwards with generic info. The DacServices.ExportBacpac method has an overload which takes a list of tables to include; so you can create a list which does not include the tables you want to skip. It turns out that it will include the tables, it just ignores the data. So we use this to, for example, grab a bacpac from prod, then import it to a local dev machine (having been sanitised because of this command that skips the sensitive data programmatically); then we run some insert scripts to populate the user table, e.g. with a global admin user with a generic password. See the overload here that takes a table list: https://msdn.microsoft.com/en-us/library/microsoft.sqlserver.dac.dacservices.exportbacpac(v=sql.120).aspx

于 2017-01-23T10:49:40.917 回答