[Android] Room 마이그레이션 방법
오늘은 Room database Migration 방법에 대해 알아보겠습니다.
Room에서 Migration은 테이블의 구조가 변경되었을 때 기존 저장된 데이터를 유지하면서
변경된 테이블 구조를 적용할 수 있는 방법입니다.
아래와 같은 User Entity에서 email colmn을 추가한다고 예를 들어보겠습니다.
@Entity(tableName = "user")
data class UserInfoEntity(
@PrimaryKey val id: Long = 0,
val name: String,
val password: String,
val email: String //추가
)
room은 이미 생성된 Entity의 구조가 변경되면 Database의 버전을 높여 주어야 합니다.
Entity의 정보가 변경되면서 무결성을 보장할 수 없기 때문에 아래와 같은 에러가 발생합니다.
따라서 기존 Entity의 구조를 변경하기 위해서는 Migration이 필수적입니다.
Room cannot verify the data integrity. Looks like you've changed schema but forgot to update the version number. You can simply fix this by increasing the version number.
Room database는 자동 마이그레이션방법과 수동 마이그레이션방법이 있습니다. 하나씩 알아보겠습니다.
Auto Migration
Android Room의 Auto Migration은 데이터베이스 스키마 변경을 자동으로 처리하는 기능입니다.
이 기능을 사용하면 개발자가 수동으로 마이그레이션 코드를 작성할 필요 없이 Room이 자동으로
데이터베이스 스키마를 업데이트합니다.
아래와 같이 DataBase 클래스 상단에 선언된 어노테이션을 아래와 같이 수정해 주면 간단하게 사용할 수 있습니다.
@Database(
exportSchema = true,
version = 2, // version 1->2
entities = [User::class],
autoMigrations = [
AutoMigration (from = 1, to = 2)
] // autoMigrations 옵션 추가
)
abstract class AppDatabase : RoomDatabase() {
...
}
※ 참고로 Auto Migration은 생성된 스키마에 의존하기 때문에
@Database 어노테이션의 exportSchema 값이 true이어야 합니다.(기본값 true)
※ Auto Migration을 사용하려면 Room 버전 2.4.0-alpha01 이상이 필요합니다.
Manual Migration
수동 마이그레이션은 아래와 같은 케이스에 해당할 경우 사용할 수 있습니다.
- 복잡한 스키마의 변경사항이 필요할 때
- exportSchema 옵션이 false일 때
- room 버전이 2.4.0-alpha01 미만일 때
Migration 클래스는 Migration.migrate() 함수를 override하여 startVersion, endVersion을 명시적으로 정의합니다.
그리고 addMigrations() 함수를 통해 데이터베이스 빌더에 추가하여 수동 마이그레이션을 사용할 수 있습니다.
val MIGRATION_1_2 = object : Migration(1, 2) {
override fun migrate(database: SupportSQLiteDatabase) {
database.execSQL("ALTER TABLE User ADD COLUMN emial TEXT")
}
}
Room.databaseBuilder(applicationContext, MyDb::class.java, "database-name")
.addMigrations(MIGRATION_1_2).build()
마이그레이션을 정의할 때는 일부 버전에는 자동 마이그레이션을 사용하고
다른 버전에는 수동 마이그레이션을 사용할 수 있습니다.
만약 동일한 데이터베이스 버전에 자동 이전과 수동 이전을 모두 정의한다면
Room은 Migration.migrate() 함수를 재정의한 수동 마이그레이션을 사용합니다.
참고: https://developer.android.com/training/data-storage/room/migrating-db-versions#kotlin