Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Refactoring Liquibase changelog files

We are using Liquibase for this project I'm working on right now, and all the changelogs are in one big XML-file. Unfortunately, this file has gotten WAY too big - and we want to introduce a "master" file, that includes the original file and any new ones.

The old structure:

/db/changesets-from-beginning-of-time.xml

The new structure:

/db/changesets/changesets-from-beginning-of-time.xml
/db/changesets/changesets-v.1.2.3.xml
/db/changesets/changeset-master.xml

The content of the changesets-* -files are simply changeset xml, while the changeset-master.xml file looks like this:

<databaseChangeLog xmlns="...skipped...">
    <include file="changesets-from-beginning-of-time.xml" 
              relativeToChangelogFile="true"/>
    <include file="changesets-v1.2.3.xml" 
              relativeToChangelogFile="true"/>
</databaseChangeLog>

Now, the DATABASECHANGELOG table in my database references the old files, and thus the old changesets are run again.

According to the Liquibase documentation, each changeset is uniquely identified by the combination [filepath/-name]:::[id]:::[author] - which is less than optimal for me.

So my question is - how do I refactor the file structure without breaking my liquibase setup and emptying my database?

like image 784
Kris Selbekk Avatar asked Sep 12 '13 15:09

Kris Selbekk


People also ask

How do I revert Liquibase changes?

The rollback command is typically used to revert all changes that were made to the database after the tag you specify. When you run rollback , Liquibase will roll back sequentially all the deployed changes until it reaches the tag row in the DATABASECHANGELOG table.

What is changelog file in Liquibase?

Liquibase changelog file is a root file that contains a record of all your database changes (changesets). The changelog-file parameter helps you create a changelog file using the generate-changelog command or diff-changelog command, apply changes to your database, and keep track of your database information.

What is the purpose of adding changesets to your changelog?

Simply put – a changelog contains an ordered list of changesets, and a changeset contains a change. You and your team can specify database changes in one of four different changelog formats: SQL, XML, JSON, or YAML. And, you can even mix and match different types of changelogs, if desired.


2 Answers

There is also something called "logicalFilePath" on liquibase which is described as:

Use to override the file name and path when creating the unique identifier of change sets. Required when moving or renaming change logs.

Maybe that helps. If I remember it correctly this option allows to not include the complete file path to the identifier.

(This does not work for formatted sql files though. See issue: CORE-915 in Liquibase Jira.

like image 195
Jens Avatar answered Sep 21 '22 20:09

Jens


I like to point to old conversation between upstream and users:

http://forum.liquibase.org/topic/why-does-the-change-log-contain-the-file-name

I think that upstream arguments are weak and they make dumb decision to relay on full file path. Initial idea that you fix file paths via CLASSPATH but your request shown that this is wrong also.

Upstream developers suggest to perform direct update on DATABASECHANGELOG.FILENAME column to fix broken entries with full paths.

If you set hashes DATABASECHANGELOG.MD5SUM to null that will trigger hashes recalculation on the next LiquiBase run. You should do this because hash algorithm uses a file path as an input.

logicalFilePath can be applied to top level XML tag:

<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
                   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                   xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.4.xsd"
                   logicalFilePath="legacy.xml">
    ...
</databaseChangeLog>

or may be overridden by each changeset:

<changeSet author="admin" id="fix-25" logicalFilePath="fix.xml">
   ...
</changeSet>

SQL syntax also have logicalFilePath attribute for top level file mark (implemented in v3.3):

--liquibase formatted sql  logicalFilePath:legacy.sql

and may be overridden in each changeset mark::

--changeset db-maint:tune-indexed  logicalFilePath:other.sql

To verify that settings have effect I use:

mvn liquibase:changelogSyncSQL

and review migration.sql. Corresponding pom.xml part:

<plugin>
    <groupId>org.liquibase</groupId>
    <artifactId>liquibase-maven-plugin</artifactId>
    <version>${liquibase.version}</version>
    <configuration>
        <changeLogFile>${basedir}/src/main/resources/sql/master.xml</changeLogFile>
        <propertyFile>${liquibase.profile}</propertyFile>
        <promptOnNonLocalDatabase>false</promptOnNonLocalDatabase>

        <migrationSqlOutputFile>migration.sql</migrationSqlOutputFile>
    </configuration>
</plugin>
like image 30
gavenkoa Avatar answered Sep 24 '22 20:09

gavenkoa