Does liquibase recognize if table is already up to date before executing changeSet? - liquibase

In our case liquibase is used to update databses for existing installation. New installations are already up to date.
Assuming we have got a new installation. Starting the application will force to execute liquibase changesets (e.g. change type of a column) but as I mentioned before there is nothing to update as the column already was created with the correct type.
Does liquibase recognize that the table column is already up to date or does it try to execute the changeset as there is no entry within the databasechangelog table for it?

Liquibase uses an alternative approach that avoids a need to analyze the target database's data dictionary. This makes DB operations simpler and more cross platform.
A special table "DATABASECHANGELOG" keeps a record of the changesets applied to the target database instance. This table also contains a checksum (calculated at runtime) to determine if changsets are altered between runs of liquibase.
So if you altered the type of a table column, liquibase can detect this and can throw an error, when run against an existing database. (Obviously, on a new DB, the table would be created as expected).
Finally, the changeset documentation describes two optional attributes ("runAlways" and "runOnChange") which could tell lqiuibase to reapply a changeset more than once to a database. There is also a "clearCheckSums" command that can be used to reset the checksums on an existing database. Obviously you need to know what you're doing when using such an option :-)

Liquibase will not recognize anything automatically.
But you can use <preConditions/> in your changeSet to check if your changeSet must be applied or not.

Related

liquibase: can I rollback a drop table by referring to a prior changeset id?

I have introduced a changeset <dropTable table_name="foo"> that will get rid of the no longer needed table foo.
Since dropTable has no auto-rollback I can of course specify the rollback actions manually (by copying the contents of the changeset that originally created foo). It would however be more convenient and less error-prone to just re-apply the said changeset - is this possible?
Update: it is possible, the answer is hidden in the Liquibase Auto Rollback subpage of using-rollback which does not only list change types and their auto-rollback capability but also has an example of referring to an older changeSetId.
However, this feature seems not to be the most powerful: if the changeset in question is stored in another file (we have all minor versions in separate files which are put together by "include file=..." tags) the changeset is not found.
Plus it's only possible to specify one changeset, so if the table in question has been created using multiple change sets (e.g. adding foreign keys in an extra step) specifying just one set to apply will not get us to the original DB setup.
That is an interesting question. 2 conditions have to be met in order to re-apply the changesets
Have a changeste with runAlways attribute (Examplel can be found here: https://docs.liquibase.com/concepts/basic/changeset.html?Highlight=runalways)
Have a precondition that is evaluated prior to running the changeset.- https://docs.liquibase.com/concepts/advanced/preconditions.html?Highlight=pre%20condition

How to generate and store the "initial" state of an existing database in Liquibase DATABASECHANGELOG table?

I'm in the process of integrating the springboot microservices with Liquibase. Prior to executing any changesets, I would like extract the "initial" state of an existing database(Oracle) and store in Liquibase DATABASECHANGELOG table. Is there way to do this?
What you would do is use the diffChangeLog command to generate a changelog.xml that contains all the changes needed to update a pristine database to the existing state of your database. If you already have a changelog, this would append to the end of that changelog, and you might want to manually rearrange the changesets so they are in the correct order.
You then use the changeLogSync command to populate the existing database with a DATABASECHANGELOG table that shows all of those changes have been deployed to that database.

Liquibase validation failed after modifying the entity

I wanted to change the data type of one field from string to date. So i dropped the table in db. Then modified the liquibase file and ran the application. now it complains with the following message.
liquibase.exception.ValidationFailedException: Validation Failed:
So after that I reverted the liquibase file changes and ran the application. This time no error but it is not creating the table.
Please help me how to solve this issue.
I assume the failed validation was an error about checksums. This happens when you modify a changeset which was already executed and try to execute it again.
Liquibase keeps all executed changesets in a table called databasechangelog, so it can find out which changesets can be skipped during execution.
To execute a changeset again, delete the corresponding from this table before, and run Liquibase again.
When using Liquibase, you shouldn't (in general) modify the database outside of Liquibase - the main exception being if you are a developer working on your own private development database. If you are in that state (working on your own private database), then when you modify the database outside of Liquibase (i.e. dropping a table) you will also need to delete the row in the DATABASECHANGELOG table that corresponds to the table create statement so that when you re-run liquibase update it will re-create the table.

Can you reference changelog id in liquibase script?

Is there anyway to reference the changeLog id in your sql? We're in the middle of moving our database over to liquibase, but we already have an Environment table which has key value pairs, one of which is "database_version". I want all our liquibase changes to also update the value for the "database_version" with the change_log id.
There is nothing built in, but the extension system (http://liquibase.org/extensions) will allow you to implement it yourself.
The easiest approach would probably be to add a liquibase.changelog.visitor.ChangeExecListener implementation updates your table after each change is executed.

liquibase does not add script to history when changeset fails

When a changeset is marked as failOnError:false, does liquibase record it as having been applied when it fails?
For example, we have a script that performs a pre-emptive drop table in one changeset and then creates the table in the next changeset. When the script is first run, the drop table statement fails as expected and then the table is created successfully. However, the changeset that attempted the drop table is not added to the databasechangelog table.
Is that expected behavior?
That is the current behavior currently. Depending on the reason for the failure, it can make sense to either continue to retry it or to not.
I created https://liquibase.jira.com/browse/CORE-1766 to add the feature to mark it as failed and not try again.
Currently, your best option would be to add a precondition to the dropTable changeSet with onFail="MARK_RAN"