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 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
- Make sure you are running the most recent version of your branch (aka, trunk, 1.5.x, etc). Someone might have committed other database changes to tables you are changing.
- Deploy this war file to get your (version specific hopefully) database up-to-date and your changes will be going against the latest version.
Step Two: Update the database script file
- Open the /metadata/model/liquibase-update-to-latest.xml file.
- Add your update to the end using liquibase's format for updates. See the liquibase manual for help.
- Use any unique string for the "id". The current date+time is an easy one e.g: 200804221449-1
- Use your trac username for the "author"
- Be sure to add a "comment" element in your changeSet, it is displayed in the webapp for end users to see
Step Three: Deploy OpenMRS to Run the Changes
- When you compile and deploy the war file, openmrs will prompt you to run the database updates. Run them now to make sure they work correctly.
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 subversion repository.
Step Five: Update the wiki datamodel changelog (Optional)
We keep tallies on each major revision changes in the Changelog. Place each of your updates on the page in the form described there. This will make it a lot easier (for the Release Manager) when it comes time for the major version change.
Never change a changeset!
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.
If a changeset contains an error, you obviously must change it. However, you should change the liquibase changeset "id" on the element when you do so to prevent errors with other developers.
= 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.
Advancing a new version
When a new minor version (1.4-->1.5) is released, the liquibase-data.zip file should be updated. This is the only time the files in the /metadata/model/liquibase-data.zip will be updated. Developers should only worry about adding their change to the liquibase-update-to-latest.xml file.