Room Database Migration in Kotlin

Alexander Portillo
2 min readApr 21, 2022

--

There are two migrating options that Room supports. There are automated migrations and manual migrations. You can use automated migrations when you are deleting or renaming a table or column, updating the primary key, adding a new column or table, etc. If you are working with a more complicated change of schema where Room cannot support automated migrations then you will have to migrate manually. I will be showing you how you can migrate your database both ways.

How to Rename a Column

When you are deleting or renaming a table or column, you will have to implement an AutoMigrationSpec. There are 4 annotations, @DeleteTable, @RenameTable, @DeleteColumn, and @RenameColumn. Since we want to rename the column, we use the @RenameColumn annotation. This is what the database class should look like.

@Database(
version = 2,
entities = [user::class],
autoMigrations = [
AutoMigration (
from = 1,
to = 2,
spec = UserDatabase.MyAutoMigration::class
)
]
)
abstract class UserDatabase : RoomDatabase() {
@RenameColumn(fromTableName = "User", toTableName = "UserInfo")
class UserAutoMigration : AutoMigrationSpec { }

}

How to Migrate Manually

Here I will be showing you what your code should look like if you need to migrate manually. First, you would want to create a migration path. This is how your code should look.

val MIGRATION_1_2 = object : Migration(1, 2) {
override fun migrate(database: SupportSQLiteDatabase) {
// this is where you would write your migration
}
}

This code is for migrating from version 1 to version 2. We will be covering what type of migrations you can use inside the migrate function in a bit. After this, you will want to add the addMigrations() method to your database builder.

Room.databaseBuilder(
applicationContext,
UserDatabase::class.java,
"User-Database"
)
.addMigrations(MIGRATION_1_2)
.build()

You finally have to change your version specified in the Database class.

@Database(entities = [User::class], version = 2)
abstract class UserDatabase : RoomDatabase() {
...
}

What To Add Inside The Migrate Method

I will be showing you different changes to your database that would require a migration change.

  1. This is how to remove an entity.
database.execSQL("DROP TABLE <name of entity>")

This is how the code would look inside the migrate function.

val MIGRATION_1_2 = object : Migration(1, 2) {
override fun migrate(database: SupportSQLiteDatabase) {
database.execSQL("DROP TABLE user")
}
}

2. This is how to add an entity.

database.execSQL("CREATE TABLE User(id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, firstName TEXT NOT NULL)")

3. This is how to change the data type

Since SQLite doesn’t support this, we need to create another table, copy all the data in the original table to the new table, delete the original table, then rename the first table.

database.execSQL("CREATE TABLE temp_user(id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, firstName TEXT NOT NULL, lastName TEXT NOT NULL)")
database.execSQL("INSERT INTO temp_user (id, firstName, lastName) SELECT id, firstName, lastName FROM Student")
database.execSQL("DROP TABLE User")
database.execSQL("ALTER TABLE temp_user RENAME TO user")

Wrap Up

I hope this article helped you understand a bit more about Room database migrations. Thanks for reading!

--

--