DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Refcards Trend Reports
Events Video Library
Over 2 million developers have joined DZone. Join Today! Thanks for visiting DZone today,
Edit Profile Manage Email Subscriptions Moderation Admin Console How to Post to DZone Article Submission Guidelines
View Profile
Sign Out
Refcards
Trend Reports
Events
View Events Video Library
Zones
Culture and Methodologies Agile Career Development Methodologies Team Management
Data Engineering AI/ML Big Data Data Databases IoT
Software Design and Architecture Cloud Architecture Containers Integration Microservices Performance Security
Coding Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Culture and Methodologies
Agile Career Development Methodologies Team Management
Data Engineering
AI/ML Big Data Data Databases IoT
Software Design and Architecture
Cloud Architecture Containers Integration Microservices Performance Security
Coding
Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance
Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks

Integrating PostgreSQL Databases with ANF: Join this workshop to learn how to create a PostgreSQL server using Instaclustr’s managed service

Mobile Database Essentials: Assess data needs, storage requirements, and more when leveraging databases for cloud and edge applications.

Monitoring and Observability for LLMs: Datadog and Google Cloud discuss how to achieve optimal AI model performance.

Automated Testing: The latest on architecture, TDD, and the benefits of AI and low-code tools.

Related

  • Migrating to Snowflake, Redshift, or BigQuery? Avoid these Common Pitfalls
  • CICD Doesn’t Have To Be a Four Letter Word for Oracle Database Developers
  • Database Migration tools: Flyway vs Liquibase
  • How to Quickly Build a Progressive Web App Using Lightning Web Components

Trending

  • Decoding the Differences: Continuous Integration, Delivery and Deployment
  • New Free Tool From Contrast Security Makes API Security Testing Fast and Easy
  • The Promise of Personal Data for Better Living
  • Getting Started With Postgres: Three Free and Easy Ways
  1. DZone
  2. Data Engineering
  3. Databases
  4. Liquibase: Git for the Database

Liquibase: Git for the Database

Liquibase is a great tool, and comparable to Git for databases. While it might not technically be a source control system, it's packed with similar functionality.

Nathan Voxland user avatar by
Nathan Voxland
·
Aug. 05, 15 · Tutorial
Like (2)
Save
Tweet
Share
8.94K Views

Join the DZone community and get the full member experience.

Join For Free

I’ve used the tag line “Liquibase: Source Control For your Database” for a few years now, despite the fact that developers are always on the lookout for categorization errors and love to argue that it’s not really a source control system because bleah, bleah, bleah. 

Nevertheless, I’ve always seen it as a good analogy despite the differences. In fact, while early versions of Liquibase used the term “migrate” as the command to apply un-run changes, I changed the command to “update” in the early 1.0 days to better match the terminology of the state-of-the-art (at the time) version control, Subversion.

So why not just use SVN or Git or any other “real” version control system for your database? Because how you manage your code and how you manage your database have a fundamental difference—it doesn’t matter how the text of your code goes from point A to point B but if the data in your database takes the wrong path from point A to point B it can have fire-able consequences. Therefore, what Liquibase specializes in is letting you specify those steps and ensuring they are executed as needed against all your databases. Those changes are stored in a text based human-readable format so that you can manage them in whatever “real” version-control system you have.

So what is the usual Liquibase workflow in terms of a version control system like Git?

Start a new project: “create an empty changelog file” aka “git init”

If you were creating a new Git-managed directory, you would run “git init” to initially set up the repository. There is no special Liquibase command to create a new database changelog, you just create an empty XML (or YAML or JSON if you prefer) file.

Start Coding: “add changeSets” aka “git add”

As you create new source files, “git add” adds the files to the index so they will be included in your next commit. In Liquibase, you add new changeSets to the databaseChangeLog file describing the steps you need done in the order they should be executed.

<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">

    <changeSet id="SAMPLE_1" author="alice">
        <createTable tableName="employee">
            <column name="id" type="int" autoIncrement="true">
                <constraints primaryKey="true"/>
            </column>
            <column name="first_name" type="varchar(255)"/>
            <column name="last_name" type="varchar(255)">
                <constraints nullable="false"/>
            </column>
        </createTable>
    </changeSet>

    <changeSet id="create address table" author="bob">
        <createTable tableName="address">
            <column name="id" type="int" autoIncrement="true">
                <constraints primaryKey="true"/>
            </column>
            <column name="line1" type="varchar(255)">
                <constraints nullable="false"/>
            </column>
            <column name="line2" type="varchar(255)"/>
            <column name="city" type="varchar(100)">
                <constraints nullable="false"/>
            </column>
            <column name="employee_id" type="int">
                <constraints nullable="false" foreignKeyName="fk_address_employee" references="employee(id)"/>
            </column>
        </createTable>
    </changeSet>

</databaseChangeLog>

Save the work you’ve done: “liquibase update” aka “git commit”

With Git, when you’re at a good stopping point, “git commit” saves your changes to your local repository. “Liquibase update” will apply your new changeSets to your local database. Once could argue that “liquibase update” is a better match for compiling your code because it is something you should do after adding each changeSet to ensure your logic is correct. Nevertheless, running “liquibase update” will look at each changeSet in turn and check the database’s DATABASECHANGELOG table to determine if it has ran or not and will only run new changeSets.

Share your work with the rest of the team: “git add; git commit; git push” aka “git push”

Once you’ve tested that your code and/or database changes work locally, it’s time to send your changes to the rest of the team. With standard Git, you’ve already added and committed your code, so you just push your commits. So far with Liquibase, however, you have just been editing a file so you need to do a standard “git add” and “git commit” on the file before “git push”-ing it along with the rest of your codebase.

@#%$&ing Conflicts: “git merge” aka “merge hell”

Just like with code, you will run into code conflicts. This is where it is valuable to have the changelog file be a human readable text format. Git and other version control systems can often seamlessly merge your changes in, but if and when it cannot, your standard merge tools will present you the opportunity to combine the changes.

Normally changelog conflicts can be resolved simply by ensuring that all your changeSets and all their changeSets are included because you have divided up the work and are all working in different areas of the database. However, there are times when you both try to add the same table or both alter the datatype of an existing column to different types. In these cases, you choose which changeSets make the most sense to keep and/or create new changeSets that combine the problem ones. Depending on how widespread the conflicts are across your databases, you may want to use liquibase preconditions or contexts to control where merged changeSets are executed.

Branching: “git branch; git merge” vs. “git branch; git merge”

Development is never straightforward, which is why branches are so invaluable. This applies to your database as much as to your code. Liquibase is designed to handle branches by tracking each changeSet individually by a combination of the id, the author, and the filename. Earlier database versioning systems would simply use an incrementing version number or a timestamp which would run into problems when multiple branches both try to add a version “42”.

With Liquibase, you lose the nice version number and instead just know that changeSets “nvoxland:3113:com/example/changelog.xml”, “nvoxland:421:com/example/changelog.xml” and “fred:421:com/example/changelog.xml” were executed. Think of it like how Git had to lose the simple SVN version numbering in favor of versions like “95ccad016ede5ded704203e632b59cc1417957c2” in order to handle distributed branches.

When you need to make a branch, simply branch the changelog file in your version control like everything else. As you append changes in your branch, those changes will be applied to just your local database. When you merge the changelog file back into the base branch, those new changeSets may end up higher in the changelog file than others that are already applied to other databases, but that is OK because each changeSet is checked individually and the newly merged changeSets will still be applied to all databases in their correct order.

Database Git Liquibase

Published at DZone with permission of Nathan Voxland. See the original article here.

Opinions expressed by DZone contributors are their own.

Related

  • Migrating to Snowflake, Redshift, or BigQuery? Avoid these Common Pitfalls
  • CICD Doesn’t Have To Be a Four Letter Word for Oracle Database Developers
  • Database Migration tools: Flyway vs Liquibase
  • How to Quickly Build a Progressive Web App Using Lightning Web Components

Comments

Partner Resources

X

ABOUT US

  • About DZone
  • Send feedback
  • Careers
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 3343 Perimeter Hill Drive
  • Suite 100
  • Nashville, TN 37211
  • support@dzone.com

Let's be friends: