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.
Related
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?
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.
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.
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.
So I want to use liquibase as a replacement for SQL scripts for preparing databases in different development environment (SIT->UAT->PROD). The plan is to execute the liquibase update (with some other parameters in place if necessary), before start doing the testing.
The caveat is, all files (including liquibase XML) that are to be submitted to UAT and PROD must have been frozen; i.e. there could be no change for any files that has successfully passed SIT. Is there any way I can do this, so that in UAT I can only execute changesets which have successfully passed SIT (and similarly, in PROD I can only execute changesets which have successfully passed UAT), without actually altering the XML file on liquibase?
Thanks.
UPDATE
There are several issues which are inherent inside the current development cycle:
It would be redundant to ask the developers to run SIT again, this time with context=SIT being put inside.
Developer(s) only wanting to test their own changesets in the UAT. So a developer is only responsible for his own changesets; meaning they don't want to run others' changesets, even if these changesets have successfully passed SIT. Same issue also applies for UAT -> PROD.
Sorry I was not clear on this issue beforehand. I was tasked to implement Liquibase on my current workplace, and I don't have a really good picture of what's really happening in the cycle.
Liquibase does not allow you to pick certain changeSets to execute. The main reason for this is because the order that changes run against a database can make a big difference. Normally it doesn't help to have developers run just their changeSets because the database changes created by others are still needed by the application.
I think the most common way to handle your scenario is to rely on the same version control practices you use for your codebase. Liquibase is designed as a simple text format so that the changelog files can be stored in version control along with your code. Then, you can have branches for UAT and PROD and you can control what is going into those branches, including what changeSets are in the changelogs.
I think the best option wouuld be to use contexts (http://www.liquibase.org/documentation/contexts.html). ChangeSets that have passed SIT can be marked as context="sit". Then when you update UAT and PROD run with context=sit and only the tagged changesets will execute.
I think that based on your valid requirements that all scripts have to be frozen in the file-based version control which is external to Liquibase you have a major challenge here.
Liquibase cannot guarantee that files are frozen - it is not for Liquibase to know that.
You are welcome to review DBmaestro Teamwork, which enables you an enforced version control on your database objects (which guarantees that the repository and workspace database are in sync). Also generating the delta scripts handles all the merges (between different environments, UAT critical fixes, branches) from changes not originating from the development env.
Disclaimer -I'm working at DBmaestro