Assume a scenario, a database
already has an apple table
with some records created manually, now Liquibase
needs to execute some ChangeSets
from a ChangeLog
file whose first ChangeSet
is itself is create apple table
followed by insert record ChangeSets
. The requirement is to execute all insert ChangeLogs
without deleting existing table Liquibse
by default doesent drop existing database object
to update with the provided in ChangeSets
.
Liquibase
needs to skip the first ChangeSet
, for this situation, Liquibase
provides the markNextChangesetRan
command, it will not execute the ChangeSet
but mark it as executed in DATABASECHANGELOG
table, once create table ChangeSet
is marked as executed, rest ChangeSet
can execute sucssfully.
execute the below query in the database
create database appleDb;
use appleDb;
create table apple (apple_id bigint not null AUTO_INCREMENT , apple_name varchar(255), available CHAR(1), current_date_time datetime default now(), primary key (apple_id), CONSTRAINT uqniue_apple_name UNIQUE (apple_name)) engine=InnoDB;
insert into apple (apple_name, available, current_date_time) values ("Macintosh", 'Y', now());
insert into apple (apple_name, available, current_date_time) values ("Fuji", 'Y', now());
commit;
The above script will create a database
, and a table
and insert some data into it.
now create a changelog.mysql.xml
file and add some insert ChangeSets
<?xml version="1.1" encoding="UTF-8" standalone="no"?>
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog" xmlns:ext="http://www.liquibase.org/xml/ns/dbchangelog-ext" xmlns:pro="http://www.liquibase.org/xml/ns/pro" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog-ext http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-ext.xsd http://www.liquibase.org/xml/ns/pro http://www.liquibase.org/xml/ns/pro/liquibase-pro-latest.xsd http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-latest.xsd">
<changeSet author="wesome" id="1697962298531-1">
<createTable catalogName="appledb" tableName="apple">
<column autoIncrement="true" name="apple_id" type="BIGINT">
<constraints nullable="false" primaryKey="true" />
</column>
<column name="apple_name" type="VARCHAR(255)">
<constraints unique="true" />
</column>
<column name="available" type="CHAR(1)" />
<column defaultValueComputed="CURRENT_TIMESTAMP" name="current_date_time" type="datetime" />
</createTable>
</changeSet>
<changeSet author="wesome" id="1697962298531-2">
<insert catalogName="appledb" tableName="apple">
<column name="apple_id" valueNumeric="1" />
<column name="apple_name" value="Gala" />
<column name="available" value="Y" />
<column name="current_date_time" valueDate="now()" />
</insert>
</changeSet>
<changeSet author="wesome" id="1697962298531-2">
<insert catalogName="appledb" tableName="apple">
<column name="apple_id" valueNumeric="2" />
<column name="apple_name" value="Jonagold" />
<column name="available" value="Y" />
<column name="current_date_time" valueDate="now()" />
</insert>
</changeSet>
</databaseChangeLog>
liquibase.properties (update changeLog File file format with SQL, XML, YAML, JSON as per changelog.mysql.)
changeLogFile=changelog.mysql.xml
liquibase.command.url=jdbc:mysql://localhost:3306/appleDb?createDatabaseIfNotExist=true&autoReconnect=true&useSSL=false&allowPublicKeyRetrieval=true
liquibase.command.username= root
liquibase.command.password= rootroot
execute the command
liquibase update
The update command
will try to execute all the ChangeSet
from the top, but since the apple table
already exists in the database
, the command will fail, we need to mark the create table ChangeSet
as already executed by running the command
liquibase markNextChangesetRan
Liquibase
will insert an entry for create table ChangeSet
in DATABASECHANGELOG
table without actually executing it and the same can be verified by executing the query
select * from appleDb.DATABASECHANGELOG;
now the update command
will work file
liquibase update