为什么在更新时未指定时执行所有上下文?

jav*_*avg 10 liquibase

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

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

所以

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

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

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

在Liquibase上下文示例中:http://www.liquibase.org/documentation/contexts.html("使用上下文测试数据")他们说,应该用"test"标记用于测试的变更集,并执行它们给出上下文"test"以应用testdata.很好 - 有意义.但

"在迁移生产数据库时,不要包含"测试"上下文,并且不包括测试数据."

因此,如果我在执行生产更新时不指定"测试"上下文,它也会执行"测试"更改集,因为我根本没有指定上下文.

同样,我希望在更新执行时省略测试,只会在没有测试更改集的情况下执行常规更改集.

或者我在这里遗漏了一些东西:)?

Ste*_*nie 11

这就是Liquibase的工作原理 - 如果您执行更新并且未指定上下文,则所有更改集都被视为适用于该更新操作.

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

  1. 如果在更新操作期间未指定上下文,则不会考虑任何更改集.
  2. 如果您未指定上下文,则会考虑所有更改集.
  3. 如果未指定上下文,则仅考虑不具有上下文的更改集.
  4. 如果您未指定上下文且没有任何变更集具有上下文,则会考虑所有变更集,但如果某些变更集确实具有上下文,请转到上面的选项1,2或3.

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


Prz*_*wak 7

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

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

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

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


小智 5

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

资料来源:https ://forum.liquibase.org/t/using-context-for-development-only-and-production-changesets/980/2