Database Migrations

When you first ship your app, you think that your database schema is beautiful, a true work of art.

Then, you wake up the next morning and realize that you need to make changes to that schema.

During initial development — and for silly little book examples — you just go in and make changes to your entities, and Room will rebuild your database for you. However, it does so by dropping all of your existing tables, taking all the data with it. In development, that may not be so bad. In production… well, users get somewhat irritated when you lose their data.

And that is where migrations come into play.

What’s a Migration?

As mentioned in the preceding chapter, with traditional Android SQLite development, we typically use SQLiteOpenHelper. This utility class manages a SQLiteDatabase for us and addresses two key problems:

  1. What happens when our app first runs on a device — or after the user has cleared our app’s data — and we have no database at all?
  2. What happens when we need to modify the database schema from what it was to some new structure?

SQLiteOpenHelper accomplishes this by calling onCreate() and onUpgrade() callbacks, where we could implement the logic to create the tables and adjust them as the schemas change.

While onCreate() worked reasonably well, onUpgrade() could rapidly grow out of control. Long-lived apps might have dozens of different schemas, evolving over time. Because users are not forced to take on app updates, our apps need to be able to transition from any prior schema to the latest-and-greatest one. This meant that onUpgrade() would need to identify exactly what bits of code are needed to migrate the database from the old to the new version, and this could get unwieldy.

Room addresses this somewhat through the Migration class. You create subclasses of Migration — typically as Kotlin object implementations — that handle the conversion from some older schema to a newer one. You pass a bunch of Migration instances to Room, representing different pair-wise schema upgrade paths. Room then determines which one(s) need to be used at any point in time, to update the schema from whatever it was to whatever it needs to be.

Prev Table of Contents Next

This book is licensed under the Creative Commons Attribution-ShareAlike 4.0 International license.