Room Database Migrations
Note: This article is part of the advanced Room series which covers all the details about the Room persistence library. You can read all the articles here:
- Introduction to Room Persistent Library in Android
- Data Access Objects - DAO in Room
- Entity Relationship in Room
- How does Room work internally?
- Room Database Migrations [You are here]
- Using Room with LiveData and other third-party libraries
So, let's get started.
Database migration is a very important concept in any application development. As we add and change features in your app, we have to update the schema of our database. Whenever there is a change in the schema of any of our tables, we need to write a migration for the existing application if we don’t want our users to lose all of their existing data.
For example, we can consider a table named
which contains information of users and it has 3 columns named
users
,
uid
and
first_name
. Now if we add a new column for
last_name
, we need to write a migration for altering the current table schema — i.e., adding a new column named
age
.
age
The
Room persistence library
allows us to write
classes to preserve user data in this manner. Each
Migration
class specifies a
Migration
and
startVersion
. At runtime, Room runs each Migration class's
endVersion
migrate()
method, using the correct order to migrate the database to a later version.
val MIGRATION_1_2 = object : Migration(1, 2) {
override fun migrate(database: SupportSQLiteDatabase) {
database.execSQL("ALTER TABLE users ADD COLUMN age INTEGER")
}
}
Now we have created the migration object
, we need to add it in the database configuration using database builder.
MIGRATION_1_2
Room.databaseBuilder(
applicationContext,
UserDatabase::class.java,
"users-db"
).addMigrations(MIGRATION_1_2)
.build()
Gracefully handle missing migration paths
After updating our database’s schemas, it’s possible that some on-device databases could still use an older schema version. If Room cannot find a migration rule for upgrading that device’s database from the older version to the current version, it throws an
which makes our app to crash.
IllegalStateException
To prevent the app from crashing when this situation occurs, call the
builder method when creating the database.
fallbackToDestructiveMigration()
Room.databaseBuilder(
applicationContext,
UserDatabase::class.java,
"users-db"
).fallbackToDestructiveMigration()
.build()
The destructive recreation fallback logic includes several additional options:
-
If errors occur in specific versions of your schema history that you cannot solve with migration paths, use
fallbackToDestructiveMigrationFrom()
-
To perform a destructive recreation only when attempting a schema downgrade, use
fallbackToDestructiveMigrationOnDowngrade()
This is how migration is done using Room. Hope you enjoyed this blog. In the next blog, we are going to learn: Using Room with LiveData and other third-party libraries .
You can also connect with me on LinkedIn , Twitter , Facebook and Github .
Thank You!!!