So you want to make a data model change?

When creating new features in OpenMRS, it is often necessary to change some database columns, add a table, etc. Database changes are done incrementally so that anyone can update their database from any version to any version.

As of version 1.5, we use the Liquibase library to define and run each incremental changeset. The changeset file is stored in /api/src/main/resources/liquibase-update-to-latest.xml.

As each changeset is executed, it is logged in the user's liquibasechangelog table. Future runs of the changelog file will check the liquibasechangelog table first to see if the changeset has been executed. If it has, then the change is skipped.

This changeset file is shipped with the OpenMRS API jar file and so also the OpenMRS war file. When OpenMRS is started and database changes are needed, openmrs enters "maintenance mode" until an administrator logs in and runs the necessary changes.

Workflow for Adding a Change

Step One: Be sure you are running the latest version

Step Two: Update the database script file

  1. Open the /api/src/main/resources/liquibase-update-to-latest.xml file.
  2. Add your update to the end using liquibase's format for updates. See the liquibase manual for help.

Step Three: Deploy OpenMRS to Run the Changes

Step Four : Make related code changes

Obviously, all database related Hibernate mapping files must be updated to work with your new latest datamodel change.

Commit both the liquibase xml file and code changes simultaneously to the git hub repository.


Never ever change a changeset! (Well, almost never)

Once you commit something to a branch, you should assume that another developer has already checked out your code and applied the database changes! Therefore, you should not just go and modify a changeset! Instead you should add another changeset below the previous one that does the necessary modifications. That way no developers have to go and mess with their database to get the changesets to apply.

Repair the changeset by adding a later changeset (with a different "id") is the preferred approach. But if a changeset contains an error that you must correct, follow the instructions on ?How to Modify a Bad Changeset.

Preconditions are important

You should always use a precondition in your changeset and not solely rely on liquibase comparing the id to the liquibasechangelog table. This is helpful for users that are upgrading from a 1.5.3 to a 1.6.0 because there have been changes (.1, .2, and .3) that happened to both the 1.5.x branch and to trunk.

Small Changesets are good

Each changeset should only be one logical unit. This allows the changeset to have a simple precondition and makes error recovery simple if the server crashes while running an update.

About the file

When a new minor version (1.4-->1.5) is released, the file should be updated. This is the only time the files in the /metadata/model/ will be updated. Developers should only worry about adding their change to the liquibase-update-to-latest.xml file.