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
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
- Make sure you have all the latest changes: pull from git upstream, then
gradlew update
- Optional: Tag your current schema so you can revert changes later:
gradlew tag -PliquibaseCommandValue=<myTag/B-02552/etc>
- 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
- Add your changeSet(s) to your project's changelog
- Inspect SQL before applying changes:
gradlew updateSQL
- Apply the changes locally:
gradlew update
- Test application with new changes
- 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>
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
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.
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>