Our Liquibase script can not be rerun because underlying column is already gone
Consider the following changesets:
- A table "foo" is created, and "domain" is one of the columns in this table;
- A constraint (in form of an index) is placed on the column "domain";
- Column "domain" is dropped from the table "foo".
Now when we try to rerun all liquibase scripts (over already existing DB structure), changeset 2 fails with
[ERROR] Reason: liquibase.exception.DatabaseException: ERROR: column "domain" named in key does not exist
all because the "domain" column in the actual DB is already gone before changeset 2 is run.
Is there any better way to make these changesets runnable other than recreating the "domain" column in the table so that all 3 changesets can run?
- there are hundreds of changesets in the system besides the 2 above;
- the solution is strongly preferred to avoid any manual steps because there are dozens of environments in which the changesets must be rerun;
- In a perfect world, a developer would have placed a preConditions on changeset 2 to check that not only the index is missing, but the underlying column exists, but we have to deal with what we have. It is my understanding that rewriting existing changesets is strongly discouraged in liquibase.
CodePudding user response:
You can always add a preCondition to the changeSets #2 and #3 to check that the domain
column exists, e.g.:
<preConditions onFail="MARK_RAN">
<columnExists tableName="foo" columnName="domain"/>
</preConditions>
If these changeSets will start to fail with the "different checksum error", than you can always provide the new checksum or just add <validCheckSum>ANY</validCheckSum>
.
This way you'll be able to run these changeSets in all environments you need.
Rewriting the changeSets is discouraged, but writing preConditions for the changeSets is quire encouraged.
CodePudding user response:
According to the comment, your problem is changing liquibase
scripts directory location.
What actually happens is liquibase
will compare liquibase
script's relative path when executing these changesets
in your scripts. You can find this relative path in the databasechangelog
table and under column filename
.
First thing you should understand is problem is not with the checksum
. So it will not solve your problem.
The easiest thing that you can do is change the values in column filename
in table databasechangelog
. If you have more than one liquibase
script files I suggest you to change them one by one. Simple sql query like this can do the job.
update databasechangelog set filename='<new_filename>' where filename='<old_filename>'
Note: You can make the situation worse if you did it wrong. Make sure you double check everything before you make any changes.