[Kotlin]Roomのデータ構造を更新する手順(migration)


概要

Roomデータベースのデータ構造を更新する時に大切なポイントをまとめてみました。migrationを使えばアプリ内のデータベース情報も正常に引き継ぐことができます。

ここで紹介するのはmigration機能を使った更新の仕方です。autoMigrationを使った更新はここをご覧ください。

列を追加したい時の手順

例として「member」という列を追加してみます。

@Databaseの修正

Entityを更新した時はversionの数字を増やす必要があります。

更新前

@Database(entities = [ToDoTask::class], version = 1, exportSchema = true)
abstract class ToDoDatabase: RoomDatabase() {
   abstract fun toDoDao(): ToDoDao
}

更新後

@Database(entities = [ToDoTask::class], version = 2, exportSchema = true)
abstract class ToDoDatabase: RoomDatabase() {
    abstract fun toDoDao(): ToDoDao
}

「exportSchema = true」を指定するとRoomがバージョン管理をするために使用するjsonファイル(スキーマ)を出力してくれます。
もしexportSchema = falseにする時は以下の「フォルダの指定」は記述しなくても大丈夫です!

スキーマの書き出しフォルダの指定

@Databaseに「exportSchema = true」を指定した場合、スキーマの出力先フォルダを「build.gradle(:app)」に記述しておく必要があります。

defaultConfig {
   kapt {
       arguments {
           arg("room.schemaLocation", "$projectDir/schemas")
       }
   }
}

@Entityの修正

memberを追加しておきます。

更新前

@Entity(tableName = "todo_table")
data class ToDoTask (
   @PrimaryKey(autoGenerate = true)
   val id: Int = 0,
   val title: String,
   val description: String,
)

更新後

@Entity(tableName = "todo_table")
data class ToDoTask (
   @PrimaryKey(autoGenerate = true)
   val id: Int = 0,
   val title: String,
   val description: String,
   val member: String,
)

migration用のSQL文

ここでは列を追加するSQL文を記述します。
Migration(~,~)部分に更新前と更新後のバージョンを書いておきます。

val MIGRATION_1_2 = object : Migration(1, 2) {
    override fun migrate(database: SupportSQLiteDatabase) {
        database.execSQL("ALTER TABLE todo_table ADD COLUMN member TEXT DEFAULT 0 NOT NULL")
    }
}

Room生成部分に.addMigrations()でSQLを指定します。

Room.databaseBuilder(
        context,
        ToDoDatabase::class.java,
        DATABASE_NAME
    ).addMigrations(MIGRATION_1_2).build()

補足1

新規テーブルを作る場合はこんな感じに記述します!
参考公式HP

val MIGRATION_1_2 = object : Migration(1, 2) {
  override fun migrate(database: SupportSQLiteDatabase) {
    database.execSQL("CREATE TABLE `Fruit` (`id` INTEGER, `name` TEXT, " +
      "PRIMARY KEY(`id`))")
  }
}

補足2

Androidエミュレータ内のデータベースを確認したい時はDatabase Inspectorが便利です。
AndroidStudioの標準機能です。
https://developer.android.com/studio/inspect/database?hl=ja