【问题标题】:When using Continuous or Automated Deployment, how do you deploy databases?使用持续或自动部署时,如何部署数据库?
【发布时间】:2014-05-07 15:26:36
【问题描述】:

我正在考虑为 CI 和按需部署实施 Team City 和 Octopus Deploy。但是,数据库部署会很棘手,因为许多旧的 .net 应用程序具有混乱的数据库。

Redgate 似乎有一个不错的 Team City 插件,但价格可能会成为绊脚石

你用什么?我很乐意执行脚本,但这是比较方面(即发生了什么变化)我正在苦苦挣扎。

【问题讨论】:

    标签: database continuous-integration continuous-deployment


    【解决方案1】:

    我们研究了 RedGate 解决方案,并得出了几乎与您相同的结论,不幸的是,成本使我们偏离了这条路线。

    我唯一能想到的就是根据您现有的数据库生成受版本控制的数据库迁移脚本,然后在构建过程中执行这些脚本。如果您正在查看未来的 .NET 项目(不使用 CMS),可能会考虑使用实体框架代码首先迁移。

    【讨论】:

    • Code first EF 非常适合新项目,绝对是这样做的方式。但对于遗产,这要复杂得多
    【解决方案2】:

    我记得不久前研究过这个问题,对我来说,似乎你必须对这种过程充满信任,因为自动部署到开发或测试服务器不是太糟糕了,因为数据可能是可替换的......但是自动更新 UAT 或生产服务器的想法可能会让运营团队背上他们,他们可能负责数据库,或者至少恢复它,如果不太对。

    话虽如此,但我确实认为这是要走的路,因为它太容易害怕数据库部署脚本,而这就是事情被遗忘或遗漏的时候。

    我似乎记得使用 Red Gate 的 SQL 比较和 SQL 数据比较工具,因为(我认为)有一种命令行方式,可以很好地与脚本化部署过程配合使用,例如 Team City、CruiseControl。网等

    【讨论】:

    • 我认为这绝对是要走的路,通过章鱼或类似的方式部署站点感觉不对,然后手动升级数据库。
    • 如果您在其中一项新功能中发现了一个重大错误,并且您决定要将您的活动站点恢复到以前的版本,那么恢复代码很简单——只需重新部署一些旧版本即可。但是对于数据库方面,你必须有后备脚本。在迁移方法(Laravel、RoR)中,这意味着确保down() 命令安全地处理真实的生产数据。此外,将 down 迁移导出到原始 SQL 可能有助于手动恢复。
    【解决方案3】:

    使用关系数据库时,风险和复杂性会更多。在一个一切都是“文档”的 NoSQL 数据库中,我想持续部署不是一个问题。在通过新发布的代码更新之前,某些对象将具有“旧”数据结构。在这种情况下,您的代码可能需要能够支持不同的数据结构。无论如何,缺失的属性或具有不同类型的属性可能应该包含在编写良好、防御性编码的应用程序中。

    我可以看到针对生产数据库运行脚本的风险,但是 CI 和持续交付的重点是这些脚本将首先在其他环境中运行和测试,以消除任何“陷阱”:-)

    但这并不会减少您实际按下按钮进行部署时手指交叉和畏缩的次数!

    【讨论】:

    • 现在你在炫耀!不,我们使用的是无聊的旧 SQL Server :(
    • NoSQL 的风险很大。如果您不将旧表单迁移到新表单,您将有很多重复的代码来管理不同的结构。这不仅体现在必须查找 .Name.Split(' ') 与 .FirstName 和 .LastName 的应用程序代码中,还体现在您的查询中。
    【解决方案4】:

    我们使用一个名为 RoundhousE 的免费工具来处理我们项目中的数据库更改,并且它与 Octopus Deploy 一起使用非常容易。

    我们在我们的解决方案中创建了一个名为 DatabaseMigration 的新项目,在项目中包含 RoundhouseE exe,我们在其中保存 RoundhouseE 的数据库更改脚本的文件夹,然后利用 Octopus 在之前、期间和之前调用 powershell 脚本的方式部署后(分别为 PreDeploy.ps1、Deploy.ps1 和 PostDeploy.ps1)并将 Deploy.ps1 添加到项目中,其中包含以下内容:

    $roundhouse_exe_path = ".\rh.exe"

    $scripts_dir = ".\Databases\DatabaseName"

    $roundhouse_output_dir = ".\输出"

    if ($OctopusParameters) {

    $env = $OctopusParameters["RoundhouseE.ENV"]

    $db_server = $OctopusParameters["SqlServerInstance"]

    $db_name = $OctopusParameters["DatabaseName"]

    } 否则 {

    $env="本地"

    $db_server = ".\SqlExpress"

    $db_name = "数据库名称" }

    &$roundhouse_exe_path -s $db_server -d $db_name -f $scripts_dir --env $env --silent -o > $roundhouse_output_dir

    在那里你可以看到我们在哪里检查 Octopus 运行部署脚本时传入的任何 octopus 变量(参数),否则我们使用一些默认值,然后我们只需调用 RoundhouseE 可执行文件。

    然后,您只需将该项目作为为 Octopus 打包的内容的一部分,然后在 Octopus 中添加一个步骤来部署该包,它将作为每个部署的一部分执行。

    【讨论】:

    • 我前段时间听说过这个并且忘记了它,这听起来很不错。我认为我可以告诉圆屋从哪个版本升级?
    • 是的,您可以指定版本号。您可以指定此编号,也可以从您的项目或 xml 文件的 dll 的程序集信息中获取它,如下所示:github.com/chucknorris/roundhouse/wiki/Versioning
    【解决方案5】:

    让数据库部署自动化是一项真正的挑战,尤其是在尝试执行构建时,一旦部署多种方法,就像对本地应用程序代码所做的那样。

    在构建一次部署多个时,您编译代码并创建二进制文件,然后将它们复制到环境中。从数据库的角度来看,相当于一次生成脚本并在所有环境中执行。这种方法不处理来自不同分支的合并、进程外更改(生产中的关键修复)等......

    我所知道的适用于 database deployment automation(免责声明 - 我在 DBmaestro 工作),因为我从我的客户那里听说它正在使用按需构建和部署方法。使用此方法,您可以将数据库增量脚本构建为部署(执行)过程的一部分。使用基线感知分析,解决方案知道是否为更改生成部署脚本或保护目标而不恢复它或暂停并允许您合并更改并解决冲突。

    【讨论】:

      【解决方案6】:

      考虑一个简单的解决方案,我们已在此线程中成功尝试过 - How to continuously delivery SQL-based app?

      免责声明 - 我在 CloudMunch 工作

      【讨论】:

        【解决方案7】:

        我们在 Visual Studio 解决方案中使用 Octopus Deploy 和数据库项目。

        1. 构建代理使用带有 dacpac 文件的 octopack 创建 nuget 包,并在其中发布配置文件并将其推送到 NuGet 服务器。
        2. 然后发布过程利用SqlPackage.exe 实用程序为发布环境生成更新脚本并将其作为工件添加到发布中。
        3. 先前创建的脚本在下一步中使用SQLCMD.exe 实用程序执行。

        创建和执行步骤的这种分离使我们有可能在两者之间进行手动步骤,以便有人在脚本在 Live 环境中执行之前进行验证,更不用说在发布中保存为工件的脚本始终可以以后可以参考。

        是否有要求我提供更多详细信息和步骤脚本。

        【讨论】:

          猜你喜欢
          • 2012-10-30
          • 2013-04-17
          • 2019-01-25
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2014-04-08
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多