Android Room Upgrade Database Add New Table (Migration) - Kotlin

Oct 22, 2018

Configure Module build.gradle to export schema and allow testing. Observe // NEW comments.

Based on Android Room Database Migration Instrumented Unit Test.

android {
    ...

    // https://developer.android.com/training/data-storage/room/migrating-db-versions
    defaultConfig {
        ...

        // NEW
        javaCompileOptions {
            annotationProcessorOptions {
                arguments = ["room.schemaLocation": "$projectDir/schemas".toString()]
            }
        }
    }

    // NEW
    sourceSets {
        androidTest.assets.srcDirs += files("$projectDir/schemas".toString())
    }
}

dependencies {
    def android_room_version = '1.1.1'
    implementation "android.arch.persistence.room:runtime:$android_room_version"
    kapt "android.arch.persistence.room:compiler:$android_room_version"
    // NEW
    androidTestImplementation "android.arch.persistence.room:testing:$android_room_version"
}

Make sure exportSchema = true for @Database, else schema json won't be generated and later you might bump into FileNotFoundException: Cannot find the schema file in the assets folder.

@Database(entities = [(Pin::class)], version = 1, exportSchema = true)@TypeConverters(RoomConverters::class)abstract class AppDatabase : RoomDatabase() {    abstract fun pinDao(): PinDao}

Make/Compile/Build project (don't Run/Deploy) and it shall generate 1.json at assets/[DatabaseClassPath] (Android view) or /app/schemas/[DatabaseClassPath] (Project view).

Change Database Version to 2.

NOTE: Important to change Database Version before applying changes to table and column. This is to ensure the database schema generated is accurate based on the database version.

@Database(entities = [...], version = 2, exportSchema = true)

Create the new Entity/Table.

@Entity(tableName = "album")data class Album (        @PrimaryKey(autoGenerate = true)        @ColumnInfo(name = "id") var id: Long = 0,        @ColumnInfo(name = "created") var created: LocalDateTime = LocalDateTime.now(ZoneOffset.UTC),        @ColumnInfo(name = "modified") var modified: LocalDateTime = created,        @ColumnInfo(name = "name") var name: String = ""        )

Add to @Database annotation.

@Database(entities = [(Pin::class), (Album::class)], version = 2, exportSchema = true)

Make/Compile/Build project (don't Run/Deploy) and it shall generate 2.json at assets/[DatabaseClassPath] (Android view) or /app/schemas/[DatabaseClassPath] (Project view).

Look inside 2.json and you shall find the createSql for new album table.

{
  "tableName": "album",
  "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER NOT NULL, `created` INTEGER NOT NULL, `modified` INTEGER NOT NULL, `name` TEXT NOT NULL, PRIMARY KEY(`id`))",
        
}

Based on Android Room Database Migration (Upgrade Version), create the Migration class.

Create file DatabaseMigration.kt to handle database migration from Version 1 -> 2.

Copy the createSql from 2.json. Replace ${TABLE_NAME}.

val MIGRATION_1_2: Migration = object : Migration(1, 2) {    override fun migrate(database: SupportSQLiteDatabase) {        // https://developer.android.com/reference/android/arch/persistence/room/ColumnInfo        /*        database.execSQL("ALTER TABLE pin "                + " ADD COLUMN is_location_accurate INTEGER NOT NULL DEFAULT 0")        database.execSQL("UPDATE pin "                + " SET is_location_accurate = 0 WHERE lat IS NULL")        database.execSQL("UPDATE pin "                + " SET is_location_accurate = 1 WHERE lat IS NOT NULL")                */        database.execSQL("CREATE TABLE IF NOT EXISTS `album` (`id` INTEGER NOT NULL, `created` INTEGER NOT NULL, `modified` INTEGER NOT NULL, `name` TEXT NOT NULL, PRIMARY KEY(`id`))")"    }}

Add addMigrations to Room.databaseBuilder.

val database = Room.databaseBuilder(app, AppDatabase::class.java, "PixPin.db")        // addMigrations(MIGRATION_1_2, MIGRATION_2_3)        .addMigrations(MIGRATION_1_2)        .build()

If you want to test it before deploying the migration to your device, refer to Android Room Database Migration Instrumented Unit Test.

Else, Run the project.

References:

❤️ Is this article helpful?

Buy me a coffee ☕ or support my work via PayPal to keep this space 🖖 and ad-free.

Do send some 💖 to @d_luaz or share this article.

✨ By Desmond Lua

A dream boy who enjoys making apps, travelling and making youtube videos. Follow me on @d_luaz

👶 Apps I built

Travelopy - discover travel places in Malaysia, Singapore, Taiwan, Japan.