Sometimes we have the problem that the database was changed outside of liquibase. In that case,
the updates could not be applied, the changes or part of the change had already been applied.
While it's certainly worth to investigate, how/why the database schema was changed without letting
liquibase control that change, there are (at least for MySQL) some options to make the changes more defensive:
An "ALTER TABLE D.A ADD COLUM b VARCHAR(10)" could be wrapped for MySQL into an if condition like this
SELECT COUNT(*) into @exist FROM information_schema.COLUMNS WHERE TABLE_SCHEMA = 'D' AND TABLE_NAME = 'A' AND COLUMN_NAME = 'b';
set @query = IF(@exist <= 0, 'ALTER TABLE D.A ADD COLUMN b VARCHAR(10)', 'Select \'Column already exists\'');
prepare stmt from @query;
EXECUTE stmt;
The check should of course be extended to also verify the column type.
The same can be done with CREATE TABLE and DROP TABLE changes. Create table would drop the table before (if exists):
DROP TABLE IF EXISTS A;
CREATE TABLE A (C VARCHAR(10));
A drop table would simply have the "IF EXISTS".
That way, the database update would not fail, if the same change has been already applied without using liquibase. The resulting schema should be the same, the changeset should be marked as executed.
Do you think, this would be a useful improvement to be integrated into liquibase?
Regards,
Andreas