概要
Roomデータベースのデータ構造を更新する時に大切なポイントをまとめてみました。autoMigrationを使えばアプリ内のデータベース情報も正常に引き継ぐことができます。
ここで紹介するのはautoMigration機能を使った更新の仕方です。使用するためにはRoomのバージョンが2.4.0-alpha01以降である必要があります。
列を追加したい時の手順
例として「member」という列を追加してみます。
@Databaseの修正
Entityを更新した時はversionの数字を増やす必要があります。一緒にautoMigrationsを追加して、元バージョンと新しいバージョンを記述します。
更新前
@Database(entities = [ToDoTask::class], version = 1, exportSchema = true)
abstract class ToDoDatabase: RoomDatabase() {
abstract fun toDoDao(): ToDoDao
}
更新後
@Database(entities = [ToDoTask::class], version = 2, exportSchema = true,
autoMigrations = [
AutoMigration (from = 1, to = 2)
]
)
abstract class ToDoDatabase: RoomDatabase() {
abstract fun toDoDao(): ToDoDao
}
ちなみに、更に更新したくなった時はこんな感じで積み重ねていきます
@Database(entities = [ToDoTask::class], version = 3, exportSchema = true,
autoMigrations = [
AutoMigration (from = 1, to = 2),
AutoMigration (from = 2, to = 3)
]
)
abstract class ToDoDatabase: RoomDatabase() {
abstract fun toDoDao(): ToDoDao
}
exportSchema = falseだとautoMigrationを使うことができません。
exportSchema = trueにしてバージョンを上げる前とあげた後のスキーマが必要になります。
(exportSchemaを省略した時はデフォルトのtrueになります)
スキーマの書き出しフォルダの指定
@Databaseに「exportSchema = true」を指定するとRoomがバージョン管理をするために必要なjsonファイルを出力してくれます。
出力先フォルダを「build.gradle(:app)」に記述しておく必要があります。
defaultConfig {
kapt {
arguments {
arg("room.schemaLocation", "$projectDir/schemas")
}
}
}
@Entityの修正
項目を追加するためにはデフォルト値を指定しないとエラーが出るので、以下のように指定します。
更新前
@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,
@ColumnInfo(defaultValue="0") val member: String,
)
列の名前を変更したい時の手順
例として「description」を「memo」に変更します。
@Databaseの修正
@RenameColumnアノテーションを追加したり、記述が多くなります。
@Database(entities = [ToDoTask::class], version = 2, exportSchema = true,
autoMigrations = [
AutoMigration (from = 1, to = 2, spec = ToDoDatabase.MyAutoMigration::class)
]
)
abstract class ToDoDatabase: RoomDatabase() {
@RenameColumn(
tableName = "todo_table",
fromColumnName = "description",
toColumnName = "memo"
)
class MyAutoMigration : AutoMigrationSpec
abstract fun toDoDao(): ToDoDao
}
@Entityの修正
列の名前を新しい名前に変更しておきます。
(AndroidStudioのRenameを使えば、対象箇所も一緒に変更できて楽です!)
@Entity(tableName = "todo_table")
data class ToDoTask (
@PrimaryKey(autoGenerate = true)
val id: Int = 0,
val title: String,
val memo: String,
)
補足1
プロジェクトのフォルダをapp > schemas > [プロジェクト名]と辿ると、バージョンアップに使われたjsonファイルを確認する事も出来ます。
補足2
Androidエミュレータ内のデータベースを確認したい時はDatabase Inspectorが便利です。
AndroidStudioの標準機能です。
https://developer.android.com/studio/inspect/database?hl=ja
こちらは公式の動画で、Migration / autoMigrationの説明が出てきます
https://www.youtube.com/watch?v=i5coKoVy1g4
参考にしたstackoverflow