Liquibase diffChangelog does not generate rollback - liquibase

If I haven't misunderstood anything, the liquibase command diffChangelog should be able to generate rollback change sets for some types of change sets like create table, rename column or add column but it is not working for me using the liquibase gradle plugin version 2.0.2. Running a command like this:
./gradlew diffChangelog -PrunList='diffLocal' -PchangeLogFile='changelog1.mysql.sql'
generate create tables change sets fine but it does not add the rollback part. Did I misunderstood that Liquibase is able to do that for me?
I am using liquibase-core version 3.8.9 and liquibase-groovy-dsl version 2.1.1. I have tried many change log file formats like xml,yaml,groovy and json but none of them adds the rollback. Even with a License Key PRO rollbacks are not added.
Any idea?

Related

Does liquibase have a method to test a rollback strategy without actually executing it?

I am brand new to Liquibase...
Today I wrote a Liquibase changeset using --liquibase formatted sql.
I created two tables where the second had a foreign key dependency on the first.
My rollback strategy was (mistakenly) drop table1; drop table2. When I ran the update and tested the rollback it failed because of the foreign key constraint. However, when I corrected my mistake and attempted to rerun it, it failed because the checksum didn't match.
I know that the obvious answer is to make more atomic changesets, however...
Does Liquibase support a way to test this sort of thing without actually running it so I can avoid the problem with the checksum on the edited rollback?
Failing that: is there a workaround for the checksum problem that will let me edit my files after running the update? (ctrl+z?)
The short answer to your question is, no Liquibase doesn't have such a thing.
Liquibase is a great toolkit, but it doesn't have a lot of bells and whistles, and it doesn't have much of an 'opinion' on how it should be used, or what your workflow should be. In your case, I would suggest that one way to deal with the problem is to just drop the database and then re-create it from the changelog. If you have already deployed the changelog in multiple places, that might not be possible, and if you weren't prepared to do that, that could be a problem.
There is an option to specify a validChecksums attribute on a changeset, so you could use that, but in general if you are using that you are making your changelog more complicated.
If you wanted to look at something that is more full-featured and that has the ability to forecast changes before they are deployed, please check out my company's product, Datical DB. It uses liquibase at its core, but adds a whole lot more (and is priced accordingly).
Liquibase provides updateTestingRollback command that basically updates the database, then tests its rollback and if successful, applies the changes again.
Your problem with invalid checksums may be solved with clearCheckSums command. It removes current checksums from database and on next update change sets that have already been deployed will have their checksums recomputed, and change sets that have not been deployed will be deployed.
For more details check Liquibase commands.

Liquibase: Deleting Sql File used in Changeset

we are using liquibase for our DB-Deployment. We are currently doing some refactoring. There is an old changeset which is running an sql script. This has been executed in the past. Now this sql script (or the statement in it) is outdated and I would like to deleted from our VCS System. I did that and tried to deploy again, but I am getting an exception saying that the sql file is not there, although my Changeset has runAlways="false" and runOnChange="false".
Does this mean that I have to always keep the specific sql script always in my CVS although it is deprecated?
According how checksum works on Liquibase, you can't delete it. Technically you run that changeset one time, and something happened on DB, then liquibase created a checksum for your file. Now if you change some part of it, liquibase will say your file is updated and you can't do that.
So in summary, your file is part of the story of your application build, even if it is no longer useful, and you can't get rid of it.
If you are not in production case, one solution could be create a dump from your current database as init.sql and start from that.
I hope this helps you.

Liquibase: runOnChange + rollback

According to Liquibase docs stored procs/triggers etc should be stored separately in a single copy and added to changeset with runOnChange to update them for each change. But what is a recommended way to rollback to the previous change? The only idea that I have is to copy them to a separate folder for each release and add apply operation of this version as a rollback (for example, have sql\procs\current for last version all added to changelog as apply and sql\procs\1.0.0 is a copy of sql\procs\current when we started new 1.0.0 release). Are there any best practices for it?
Thanks!
We keep single copy of replaceable objects (procs/triggers/views etc)
and use version control system (VCS) - git in our case.
When you want to rollback to previous version, just revert to relevant commit in VCS and run liquibase update.
Tutorial using Oracle - we are working by this tutorial for two years.

Run liquibase rollback without changelog files?

Liquibase is not able to rollback a without the changelog files.
It requires to provide the original changelogs/changesets files when running a rollback.
My questions is: Is there any way to run rollback without the files?
E.g.: Store the files (or rollback commands) in the databasechangelog table?
You could use Liquibase's "Future Rollback SQL" feature. It's exposed in several different ways.
Java API
Liquibase.futureRollbackSQL(...)
Spring Integration
SpringLiquibase.setRollbackFile(...)
Maven Integration
mvn liquibase:futureRollbackSQL
Ant Integration
<liquibase:rollbackFutureDatabase outputfile="/path/to/rollback-future.sql".../>
Command Line
liquibase futureRollbackSQL
If you use this feature in conjunction with update or updateSQL then you will be able to rollback the update without the original change logs.
As far as I know liquibase generates the rollback commands on the fly from the changesets (in those cases where this is possible).
So it will always need the changelog files to do this.
I dont't think that there is an easy solution to do this. The whole point of liquibase is to keep the changesets in separate files, so you can put them in some sort of version control system.

Can you control Liquibase updateSQL output by major release?

We use liquibase to generate database changes but need these scripted into SQL files because our DB server has neither Liquibase nor even a JVM installed.
We use the updateSQL command to create the DDL script needed to make changes, however if we run (on our development server) a 'dropAll' first we get a change set for every release.
Is there a way to run Liquibase regular 'update' for one collection of changesets (i.e. all prior releases) and then produce updateSQL output only for the last release? Essentially can we parameterize our build process to indicate the release we are targeting and automatically produce only SQL for that release?
Thanks
We have a similar setup.
The way we handle this is we have an "integration" db that always keeps the last official release.
When we have a new release candidate we let liquibase run (updateSQL) against that integration DB. Since it is on the last (resp. the current) release, updateSQL will only write out the difference between the new release candidate and the last release.
So you have a delta ddl that needs to be applied to go from release x to y.
Once the release candidate is released we let liquibase also update the integration db.
There are several ways to run a portion of your changelog.
If you break up your changelog files using versions (changelog-1.0.xml, changelog-1.1.xml, changelog-2.0.xml) and then have a master changelog.xml that <include>'s them, then the easiest solution for you may be to just run updateSql passing in the changelog version you want. If you want to generate sql for the entire database, run "liquibase --changelogFile=master.changelog.xml updateSql". If you want to generate sql for just version 2.1, run "liquibase --changeLogFile=changelog-2.1.xml updateSql"
#Jens answer works well and is what I often suggest. It has the advantage compared to the above option of catching new changeSets that were introduced into old changelog versions through a merged in patch release, for example.
Beyond that, you could use context or preconditions to dynamically control what is ran. Depending on your setup there may be ways to get those to work well for you.
Finally, there is always the extension system where you can write custom logic around how changelogs are parsed and executed to pull out older version changeSets based on file name or some other mechanism that works for you.