【问题标题】:Why are all contexts executed when non specified on update?为什么在更新时未指定所有上下文?
【发布时间】:2015-08-27 07:11:48
【问题描述】:

我正在使用 Liquibase 3.3.5 来更新我的数据库。拥有上下文是只执行变更日志的特定部分的好方法。但我不明白,当更新时没有提供上下文时,为什么要执行所有变更集。考虑以下示例:

  • 变更集 A:context=test
  • 变更集 B:无上下文
  • 变更集 C:context=prod

所以

  • 使用 context=test 执行更新,将执行变更集 A+B。
  • 使用 context=prod 执行更新,将执行变更集 B+C。
  • 在没有上下文的情况下执行更新,将执行变更集 A+B+C。

对我来说,这根本没有意义:)。

我希望只有变更集 B 会被执行,因为它没有定义特定的上下文。

在 Liquibase 上下文示例中:http://www.liquibase.org/documentation/contexts.html(“为测试数据使用上下文”)他们说,应该用“test”标记要测试的变更集,并通过给出上下文“test”来执行它们以应用 testdata .很好 - 有道理。但是

“当需要迁移生产数据库时,不要包含“测试”上下文,并且不会包含您的测试数据。 "

所以,如果我在执行生产更新时不指定“测试”上下文,它执行“测试”变更集,因为我根本没有指定上下文。

再次,我希望在更新执行时忽略测试,只会执行常规变更集而没有测试变更集。

或者我在这里遗漏了什么:)?

【问题讨论】:

    标签: liquibase


    【解决方案1】:

    这正是 Liquibase 的工作方式 - 如果您进行更新但未指定上下文,则所有变更集都被视为适用于该更新操作。

    有几种方法可以实现,开发团队必须选择一种。

    1. 如果您在更新操作期间未指定上下文,则 不考虑变更集。
    2. 如果您不指定上下文,则考虑所有变更集。
    3. 如果您不指定上下文,则只考虑没有上下文的变更集。
    4. 如果您未指定上下文并且所有变更集都没有上下文,则考虑所有变更集,但如果某些变更集确实具有上下文,请转到上面的选项 1、2 或 3。李>

    团队本可以采用选项 3(符合您的期望),但很久以前就决定采用选项 2,因为这在当时似乎是“最佳”方式。那时我不在团队中,所以我不知道更多。

    【讨论】:

    • 好的,感谢您的澄清 :)!改变它会破坏向后兼容性,这是肯定的。但作为 Liquibase 的新用户,这对我来说并不“自然”,因此提出了这个问题。如果您总是使用上下文,那么这样做似乎没问题。是否有计划改变这种行为?
    • 正如您所指出的,更改它会破坏向后兼容性,因此它不太可能更改。改进文档将是有益的。如果您有兴趣,文档都在 GitHub 中,团队欢迎拉取请求! github.com/liquibase/liquibase.github.com ps - 如果我的回答有帮助,请“接受”作为正确答案。
    【解决方案2】:

    @javg 可能为时已晚,但这可能会使未来的读者受益。 这个要求可以通过以下方式实现:

    changeset A: context=test
    changeset B: context=all
    changeset C: context=prod
    

    所以

    executing update with "context=test,all" will execute changeset A+B.
    executing update with "context=all,prod" will execute changeset B+C.
    executing update with "context=all" will only execute changeset B as you expect.
    

    【讨论】:

      【解决方案3】:

      我将添加我的解决方案(从我的角度来看,默认的 Liquibase 行为并不直观)。在我们处理“问题”的项目中,我们以这种方式配置了 liquibase 上下文:

      liquibase.setChangeLog("classpath*:liquibase/master.xml");
      contexts = StringUtils.isBlank(contexts) ? "none" : contexts;
      liquibase.setContexts(contexts);
      

      这导致 liquibase 将运行所有上下文为“无”的变更集和所有默认变更集(没有上下文的变更集)——是的,这就是它的工作原理。

      因此,选择团队中没有人不会使用的名称(在我们的例子中为“none”)作为上下文名称,然后默认使用该上下文运行 liquibase(查看示例)。使用这种方法,您将在没有任何上下文的情况下运行更改集,我认为这应该是默认方法!

      【讨论】:

        【解决方案4】:

        我只是将开发变更集标记为“dev”[或“test”],并且没有在两者中运行的变更集上指定上下文。当我对生产进行更新时,即使没有标记为 prod 的变更集,我也会在更新中指定 contexts=prod。这将使它跳过所有开发 [或“测试”] 上下文,但仍将执行所有非上下文更改集。然后,您还可以在未来某个时间点进行设置,您需要创建一个 context="prod" changeSet ... 仅在 prod 中运行。

        来源:http://forum.liquibase.org/topic/using-context-for-development-only-and-production-changesets

        【讨论】:

          【解决方案5】:

          如果您或您的管理员忘记指定上下文会怎样?是的,它会执行 A+B+C,在制作上它会破坏很多东西,让你的生活不那么快乐。

          我正在寻找一种在这些情况下受益并在开始时中止 liquibase 执行的解决方案(当您在没有任何上下文的情况下运行 liquibase 时)。

          如果 liquibase 有一个属性(在 liquibase.properties 中)来限制在有/没有上下文的情况下运行...

          作为一种解决方案,您可以将contexts=default,contexts,of,your,project 添加到liquibase.properties 文件中。

          【讨论】:

            猜你喜欢
            • 2020-11-25
            • 1970-01-01
            • 2020-11-23
            • 1970-01-01
            • 2021-04-06
            • 1970-01-01
            • 1970-01-01
            • 2014-08-12
            • 1970-01-01
            相关资源
            最近更新 更多