Skip to content

Instantly share code, notes, and snippets.

@BenArunski
Created May 26, 2017 05:50
Show Gist options
  • Save BenArunski/98edb4e9e737864ea694205260d1cdd1 to your computer and use it in GitHub Desktop.
Save BenArunski/98edb4e9e737864ea694205260d1cdd1 to your computer and use it in GitHub Desktop.

Contents

  1. Liquibase
    1. Configuration
    2. Development Workflow
    3. Best practices - Organizing Changelogs
    4. Best Practices - Preconditions

Liquibase

Use Gradle/Liquibase to apply others' recent database changes: gradlew update

To pass a value to a Liquibase command, use -PliquibaseCommandValue: gradlew tag -PliquibaseCommandValue=beforeTest

Configuration

To override the defaults, add to ~/.gradle/gradle.properties:

systemProp.dbUser=yourUser
systemProp.dbPassword=yourPassword
systemProp.npacs.dbUrl=jdbc:jtds:sqlserver://localhost:<my port>/NSC_Npacs

Development Workflow

  1. Make sure you have all the latest changes: pull from git upstream, then gradlew update
  2. Optional: Tag your current schema so you can revert changes later: gradlew tag -PliquibaseCommandValue=<myTag/B-02552/etc>
  3. If a changeLog does not exist for your project, create one in src/main/db/
    • Create one changelog per release (more or less)
    • filename: YYYY_project_name.xml
    • Create a <tagDatabase> changeSet as the first changeSet in every changeLog
    • Include the new changeLog at the end of src/main/db/npacs.xml
  4. Add your changeSet(s) to your project's changelog
  5. Inspect SQL before applying changes: gradlew updateSQL
  6. Apply the changes locally: gradlew update
  7. Test application with new changes
  8. If you need to correct your changes, first rollback to the tag at the beginning of your project changelog, or to the tag you created for this story: gradlew rollback -PliquibaseCommandValue=<myTag/B-02552/etc>

Best practices - Organizing Changelogs

One changelog per release or project effort, executed in approximate effort order via a master changelog that contains only <include> tags. Do not add changeSets directly to the master changelog.

If <precondition>s start to build up, ensure that changes are executed in order by adding a GATEWAY changeset. See PR #2037

Start every changeLog with a <tagDatabase> changeSet, so that changes can be rolled back if necessary to work on a different branch. <rollback> tags on each changSet are optional (and generally only applicable to raw SQL). Rollback tags can be added later as-needed without affecting the checksum.

We tried grouping changelogs by type, such as "lookup table inserts" and "case management stuff". That method failed -- over time it yields circular dependencies between changelogs, requiring many extra preconditions. Even precondition checks become brittle and fail eventually, for instance if a column referenced in a precondition is added and later removed.

When you move or rename a changelog, add logicalFilePath= to its <databaseChangeLog> element. Set it to the file's original location and filename. Otherwise all changesets in the file will be re-run, because the logical filename is part of the changeSet identifier.

See also:
http://www.liquibase.org/bestpractices.html
http://forum.liquibase.org/topic/why-does-the-change-log-contain-the-file-name

Best Practices - Preconditions

All precondition types are acceptable: changeSetExecuted, columnExists, tableExists, or sqlCheck. changeSetExecuted can be confusing, because it must reference the logicalFilePath, not the physical file path -- this matters once a changelog has been archived.

Example

Note the location of oldChangeLog.xml in the <include> tag is different than the location of oldChangeLog.xml in the precondition

masterChangeLog.xml

<property name="folders.2017_archive" value="src/main/db/archive/2017"/>
<include file="${folders.2017_archive}/oldChangeLog.xml"/>

newChangelog.xml

<changeSet id="brand new" author="me">
	<preConditions onFail="CONTINUE">
		<changeSetExecuted changeLogFile="src/ORIGINAL/FOLDER/oldChangeLog.xml" author="someone else" id="old"/>
	</preConditions>
</changeSet>

Back to top

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment