본문 바로가기

ANDROID/DB

[안드로이드] Room 데이터베이스의 테이블 등을 업데이트 할 시, Migration 옵션을 필히 집어넣자.

기존 프로젝트의 로컬 DB 테이블에 컬럼을 삽입해야하는 요구사항이 생겼는데, 이를 진행하면서 필수적이었던 Migration 과정을 리뷰해두고자 한다.

 

Room DB를 안드로이드에 설정할 때에는 @Database 어노테이션에 vesion number를 명시하는데,

 

신규 변경사항이 생길 경우 version number를 올려주어야 하는 것은 물론,

 

이전 버전에서 신규 버전으로 올라가면서 달라진 점들에 대해 어떻게 변경사항을 집어넣을 것인지

 

Migration이라는 클래스를 사용해 작성하여 적용해주어야 한다.

 

 

아래는 Google documentation이 예시로 들고있는 Migration Object이다.

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()

 

여러 Migration옵션을 줄 수 있는것으로 보이는데, 사용자가 가지고 있는 앱 버전이 경우에 따라 상이할 수 있고, 

 

거기에 더불어 Room Database의 버전도 상이할 수 있는데, 이같은 경우에 각 버전을 체크하고, 이를 개별적으로 적용하도록 하는 

 

과정이 필요치 않을 까 생각하는데, 이같은 경우도 추후 스터디를 하고 다루어보려 한다.

 

 

이렇게  Migration Instance를 만들어주었다면, 이를 Room Database를 build하는 부분에 .addMigration()을 통해 적용하면 된다.

...

private var INSTANCE: RoomDB? = null

fun getInstance(context: Context): RoomDB? {
	if (INSTANCE == null) {
    	syncronized(RoomDB::class) {
        	INSTANCE = Room.databaseBuilder(context.applicationContext,
            	RoomDB::class.java, "myroom.db").allowMainThreadQueries()
                .addMigrations(MIGRATION_2_3)
                .build()
      	}
	}
    return INSTANCE
}

...
    

 

여기서 Migration SQL문이나 DB상의 오류가 있을 시 기존 DB 데이터를 없앤다고 하니 테스팅이 필히 중요해보이며, 

 

관련 테스팅 방법에 대해 Google 공식 페이지에서 자세히 안내하고 있으니 참조하는 것이 좋겠다.

 

 

마지막으로 짚고 넘어가고 싶은 점은 Room의 2.1.0 버전과 2.2.0의 차이점이다.

 

이는 Google 공식 페이지에서 한 섹션 분량으로 설명을 하고 있는데, Migration 옵션을 통해 DB 버전을 업데이트 할 경우

 

2.1.0 버전에서는 기존 유저들의 버전업에선 이슈가 없으나, 신규로 앱을 설치한 사람들의 경우 추가한 컬럼의 DEFAULT 값이

 

적용되지 않는 경우가 있던 것으로 보인다.

 

 

이를 방지하기 위해 업데이트된 Room 2.2.0은 default value를 검사해 이들이 entity클래스에 적용되어 있는지 확인하는 것으로 바뀌었다고 한다.

 

추가적으로 Google은 기존의 테이블을 컬럼등의 추가/제거가 진행된 신규 테이블에 복사해 넣고, 기존 테이블을 제거하는 drop & re-create 전략을 추천하고 있다.

 

이후 포스트에서는 Migration 진행 이후 유닛테스팅에 관해 진행해보고 정리를 해보고자 한다!

 

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

 

Room 데이터베이스 이전  |  Android 개발자  |  Android Developers

Room 라이브러리를 사용하여 데이터베이스를 안전하게 이전하는 방법 알아보기

developer.android.com

 

'ANDROID > DB' 카테고리의 다른 글

[Room] Room DB 및 Firebase RDB와의 Transaction 최적화하기  (0) 2020.07.02