我正在使用Liquibase 3.3.5来更新我的数据库。拥有上下文是一种只执行更改日志的特定部分的好方法。但我不明白,为什么在更新时没有提供上下文时执行所有更改集。请考虑以下示例:
所以
对我来说,这根本没有意义:)。
我希望,只有变更集B才会被执行,因为它没有定义特定的上下文。
在Liquibase上下文示例中:http://www.liquibase.org/documentation/contexts.html(“使用上下文测试数据”)他们说,应该用“test”标记用于测试的变更集,并在给出上下文“test”的情况下执行它们应用testdata。很好 - 有意义。但
“当需要迁移生产数据库时,请不要包含”测试“上下文,并且不要包含测试数据。 “
因此,如果我在执行生产更新时不指定“测试”上下文,那么也将执行“测试”更改集,因为我根本没有指定上下文。 / p>
同样,我希望在更新执行时省略测试,只会在没有测试变更集的情况下执行常规变更集。
或者我在这里遗漏了一些东西:)?
答案 0 :(得分:10)
这就是Liquibase的工作原理 - 如果您进行更新并且没有指定上下文,则所有更改集都被视为适用于该更新操作。
有几种方法可以实现,开发团队必须选择一种方法。
团队本可以选择3(符合你的期望),但很久以前决定选择2,因为这似乎是最好的'当时的方式。当时我不在团队中,所以我不仅仅知道。
答案 1 :(得分:1)
对于@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.
答案 2 :(得分:1)
我将添加来自我的解决方案(从我的角度来看,默认的Liquibase行为不直观)。在我们的项目中处理"问题"我们以这种方式配置liquibase上下文:
liquibase.setChangeLog("classpath*:liquibase/master.xml");
contexts = StringUtils.isBlank(contexts) ? "none" : contexts;
liquibase.setContexts(contexts);
这导致liquibase将运行所有更改集与上下文'无'和所有默认的变更集(没有上下文的变更集) - 是的,这就是它的工作原理。
因此,选择团队中没有人赢得的名称(在我们的例子中没有#);作为上下文名称,然后在默认情况下使用该上下文运行liquibase(请查看示例)。使用这种方法,您将运行更改集,而不使用我认为应该是默认方法的任何上下文!
答案 3 :(得分:0)
我只是将开发变更集标记为“ dev” [或“ test”],并且没有在两个版本中运行的变更集上指定上下文。对生产进行更新时,即使没有标记为prod的变更集,我也会在更新中指定contexts = prod。这将使其跳过所有dev [或“ test”]上下文,但仍将执行所有未上下文的changeSet。然后,您还将在将来的某个时候进行设置,需要在该点上创建一个context =“ prod” changeSet,它仅在prod中运行。
来源:http://forum.liquibase.org/topic/using-context-for-development-only-and-production-changesets
答案 4 :(得分:0)
如果您或您的管理员忘记指定上下文会怎样?是的,它将执行A + B + C,在生产中会破坏很多事情并使您的生活变得不那么快乐。
我正在寻找一种可以在这些情况下受益的解决方案,并且从一开始(当您在没有任何上下文的情况下运行liquibase时)中止liquibase的执行。
如果liquibase具有一个属性(在liquibase.properties
中)来限制在有/无上下文的情况下运行,那将很酷...
作为解决方案,您可以将contexts=default,contexts,of,your,project
添加到liquibase.properties
文件中。