Why are all contexts executed if they are not specified during the update?

I am using Liquibase 3.3.5 to update my database. Having contexts is a good way to only execute certain parts of the change log. But I do not understand why all the changes are made when the context is not provided during the update. Consider the following example:

  • changeset A: context = test
  • changeet B: no context
  • changeet C: context = prod

So,

  • performing an update using context = test will execute a set of changes A + B.
  • executing an update using context = prod will execute a set of changes B + C.
  • performing an update without context will execute a set of changes A + B + C.

For me it makes no sense :).

I would expect that only change set B will be executed, since it does not define a specific context.

In the Liquibase context example: http://www.liquibase.org/documentation/contexts.html ("Using contexts for test data"), they say that changes to be tested using the "test" should be noted and implemented with the context provided "test" for applying test data. Fine - to make sense. But

"When the time comes to migrate your production database, do not include the test context, and your test data is not included."

So, if I did not specify a โ€œtestโ€ context when performing a production update, it would also make โ€œtestโ€ changes, since I did not specify a context at all.

Again, I would expect that dropping the test when performing the update would perform normal changes without test changesets.

Or am I missing something here :)?

+10
source share
5 answers

This is how Liquibase works โ€” if you perform an update and do not specify a context, then all revisions are considered applicable to this update operation.

There were several ways this could be implemented, and the development team had to choose one.

  • if you do not specify the context during the update operation, then no changes are considered.
  • If you do not specify a context, then all changes are taken into account.
  • If you did not specify a context, then only changes that have no context are taken into account.
  • If you do not specify a context, and none of the change sets has contexts on them, then all changes will be considered, but if some of the change sets have contexts, go to options 1, 2, or 3 above.

The team could go with option 3 (which matches your expectation), but decided to go with option 2 long ago, because at that time it seemed "best." At that time I was not in the team, so I do not know more than that.

+11
source

I will add a solution from me (in my opinion, the default behavior of Liquibase is not intuitive). In our โ€œproblemโ€ project, we configured the context of the educational program in this way:

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

This causes Liquibase to trigger all change shifts using the "none" context and all default change sets (shifts without context) - yes, thatโ€™s how it works.

So, choose a name that no one in your team will use (โ€œnoโ€ in our case) as the context name, and then run Liquibase by default with this context (see example). With this approach, you will start shifts without any context, which, I believe, should be used by default!

+2
source

It may be too late for @javg, but it could benefit future readers. This requirement can be achieved as follows:

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

So,

 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. 
+1
source

I simply mark development changesets as "dev" [or "test"] and do not specify the context for changesets that are executed in both. When I do an update in production, I will indicate contextx = prod in the update, even if there are no changes marked as prod. This will force all dev [or "test"] contextual development to be skipped, but still make all non-contextual changes. Then you will also tune in at some point in the future when you will need to make changeSet context = "prod", which ... only works in prod.

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

+1
source

And what happens if you or your administrator forget to specify the context? Yes, he will perform A + B + C, in production he can break many things and make your life not so happy.

I am looking for a solution that wins in these cases and interrupts working with the liquid base at the beginning (when you work with a liquid base without any contexts).

It would be great if liquibase had the property (in liquibase.properties ) to restrict work with / without contexts ...

As a solution, you can add contexts=default,contexts,of,your,project to the liquibase.properties file.

0
source

All Articles