[Database, AAC] Room 데이터베이스 마이그레이션

dwjeong·2023년 11월 2일
0

안드로이드

목록 보기
11/28

Room 엔티티 클래스와 기본 데이터베이스 테이블을 수정해야 할 경우, 기기 내에 이미 존재하는 데이터베이스의 유저 데이터를 보존하는 것이 중요.

Room은 자동 마이그레이션과 수동 마이그레이션 모두 지원.

🔎 자동 마이그레이션

Room은 2.4.0-alpha01 버전 이상에서 자동 마이그레이션을 지원하며 이보다 낮은 버전을 사용할 경우 수동으로 마이그레이션을 정의해야 함.

두 개의 데이터베이스 버전 간 자동 마이그레이션을 선언하려면 @Database의 autoMigrations 속성에 @AutoMigration 주석을 추가

// Database class before the version update.
@Database(
  version = 1,
  entities = [User::class]
)
abstract class AppDatabase : RoomDatabase() {
  ...
}

// Database class after the version update.
@Database(
  version = 2,
  entities = [User::class],
  autoMigrations = [
    AutoMigration (from = 1, to = 2)
  ]
)
abstract class AppDatabase : RoomDatabase() {
  ...
}

❗ exportSchema가 false로 설정되어 있거나 새 버전 번호로 데이터베이스를 아직 컴파일하지 않았다면 자동 마이그레이션은 실패.



📖 자동 마이그레이션 - 변경사항

Room은 모호한 스키마 변경이 발생할 경우 이름이 변경된건지 삭제된것인지 판단할 수 없음. 이 때 컴파일 에러가 발생하고 AutoMigrationSpec을 구현하도록 요청함.

  • 이런 경우가 발생하는 경우
  1. 테이블 삭제 또는 이름 변경
  2. 컬럼 삭제 또는 이름 변경

AutoMigrationSpec을 사용하여 Room에 올바른 마이그레이션 경로를 생성할 수 있도록 정보를 제공해야 함.

  • @DeleteTable
  • @RenameTable
  • @DeleteColumn
  • @RenameColumn

자동 마이그레이션에서 AutoMigrationSpec 구현을 사용하려면 @AutoMigration 주석에서 spec 속성을 설정해야 함.

@Database(
  version = 2,
  entities = [User::class],
  autoMigrations = [
    AutoMigration (
      from = 1,
      to = 2,
      spec = AppDatabase.MyAutoMigration::class
    )
  ]
)
abstract class AppDatabase : RoomDatabase() {
  @RenameTable(fromTableName = "User", toTableName = "AppUser")
  class MyAutoMigration : AutoMigrationSpec
  ...
}




📖 수동 마이그레이션

수동 마이그레이션은 복잡한 스키마 변경이 필요한 경우 사용됨.
예) 테이블의 데이터를 두 개의 테이블로 분할하기로 결정한 경우 등

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`))")
  }
}

val MIGRATION_2_3 = object : Migration(2, 3) {
  override fun migrate(database: SupportSQLiteDatabase) {
    database.execSQL("ALTER TABLE Book ADD COLUMN pub_year INTEGER")
  }
}

Room.databaseBuilder(applicationContext, MyDb::class.java, "database-name")
  .addMigrations(MIGRATION_1_2, MIGRATION_2_3).build()

마이그레이션 경로를 정의할 때 일부 버전은 자동 마이그레이션을 사용하고 다른 버전은 수동 마이그레이션을 사용할 수 있음.

동일한 버전에 대해 자동 마이그레이션과 수동 마이그레이션을 모두 정의한 경우 Room은 수동 마이그레이션을 이용함.

마이그레이션 테스트에 관한 내용

데이터베이스 테스트 및 디버그

Migration SQL to Room

0개의 댓글