fornewid / ConfDocs

Conference 내용 끄적끄적
4 stars 0 forks source link

Practical room migrations #25

Closed fornewid closed 1 year ago

fornewid commented 1 year ago
fornewid commented 1 year ago

1

모든 데이터베이스를 마이그레이션할 필요는 없다. 그래서 그냥 버려버린다. 앱의 데이터가 일종의 cache이거나 'source of truth'가 서버인 경우, 데이터베이스 마이그레이션을 수행할 이유가 없을 수 있다.

이런 경우, Room은 앱이 업데이트될 때 데이터베이스를 다시 생성할 수 있으며 빌더에서 fallbackToDestructiveMigration API로 이를 활성화할 수 있다.

2

그러나 이것이 중요한 부분입니다. 데이터베이스의 데이터가 실제로 'source of truth'라면 해당 스키마 마이그레이션을 수행하는 것이 매우 중요하다. 그렇지 않으면 사용자가 앱을 업데이트하고 그것을 잃어버린다.

3

그러면 어떻게 해야 할까요? Room을 사용하면 아주 쉬울 수 있습니다.

Room 2.0에서는 자동 마이그레이션을 활용할 수 있습니다. 마이그레이션하려는 시작 및 종료 버전을 정의하기만 하면 됩니다. Room은 스키마를 살펴보고 분석하고 마이그레이션 구현을 만듭니다. 자동 마이그레이션이 작동하려면 스키마 내보내기(=exporting the schemas)가 필수라는 것을 아는 것이 중요합니다.

자동 마이그레이션은 추가 입력, 새 열 추가, 새 테이블 추가, foreign key / indices / views 변경 없이 대부분의 작업을 즉시 처리할 수 있습니다.

4

그러나 자동 마이그레이션에 약간의 추가 정보가 필요한 경우가 있습니다. 이 예에는 table rename이 있고 Room은 이 두 스키마 파일을 보고 있습니다. 테이블이 삭제되었고 의심스러울 정도로 유사한 열이 있는 새 테이블이 생성되었는지는 실제로 알 수 없습니다.

5

이러한 유형의 경우 migration spec을 제공할 수 있습니다. 그리고 이 migration spec에서 이러한 annotation을 달아 이 모호한 상황을 해결할 수 있습니다.

6

RenameColumn, RenameTable, DeleteColumn 및 DeleteTable의 총 네 가지 주석을 사용할 수 있습니다.

7

자동 마이그레이션의 또 다른 멋진 점은 Room이 실제로 이전 테이블에서 이전 데이터를 가져와 새 테이블로 전송한다는 것입니다.

8

그러나 약간의 추가 처리를 수행해야 하는 특정 스키마 변경이 있을 수 있으며 migration spec의 onPostMigrate에서 수행할 수 있습니다.

여기에 대한 한 가지 예는 Boolean인 열이 있고, 이를 enum과 같은 문자열로 변경하려는 경우입니다. 이러한 경우 onPostMigrate에서 원하는 위치에 데이터를 가져오는 일부 쿼리를 구현하여 실행할 수 있습니다.

9

이제 마이그레이션 전에 데이터 처리를 수행해야 하는 경우, 자동 마이그레이션과 함께 수동 마이그레이션을 사용할 수 있습니다. 그리고 수동 마이그레이션과 자동 마이그레이션은 서로 호환되기 때문에, 두 번의 버전 범프(=version bump)에서도 연속적으로 수행할 수 있습니다.

아이디어는 수동 마이그레이션에서 해당 자동 마이그레이션을 준비하기 위해 필요한 데이터 변경을 수행한다는 것입니다. 예를 들어 드리겠습니다.

10

한 가지 예는 테이블이 있고 새로운 foreign key를 추가하려고 했지만, 자식 테이블에 부모 테이블에 대한 잘못된 참조가 있는 경우입니다. 따라서 foreign key를 추가하면 foreign key 제약조건 오류가 발생합니다.

11 12

따라서 수동 마이그레이션에서 데이터를 삭제하는 데 필요한 쿼리를 작성하고 해당 자동 마이그레이션을 준비한 다음

13

해당 외래 키를 추가합니다.

14

일부 마이그레이션은 SQLite를 사용하면 더 쉽습니다. 예를 들어, 알려지지 않은 새 열을 추가하는 경우 기본값을 제공해야 합니다. ColumnInfo로 이 작업을 수행하여, Room에서 데이터를 마이그레이션할 때 기존 행을 기본 데이터로 채울 수 있습니다.

fornewid commented 1 year ago

Test your migrations

따라서 마이그레이션 버그는 흔하지 않습니다. 즉, 테스트 중에 종종 간과되는 영역입니다. 그러나 마이그레이션은 정말 나쁜 버그로 이어질 수 있기 때문에, 마이그레이션을 테스트하는 것은 정말 중요합니다. 특히, 데이터베이스 업데이트를 시도하고 실패하기 때문에, 데이터베이스와 앱이 crash loop에 빠지게 만들 수 있습니다. 그리고 사용자는 결국 앱을 다시 설치하고 데이터를 잃게 됩니다. 좋지 않습니다.

16

좋은 소식은, Room이 자동 마이그레이션을 포함하여 마이그레이션 테스트를 위한 API를 제공한다는 것입니다. 권장 사항은 각 버전에 대한 테스트를 작성하는 것입니다.

또한 데이터베이스에 일부 데이터를 저장하여 확인할 수 있도록 하는 것도 좋습니다.

이렇게 하려면 MigrationTestHelper API를 사용하고 이전 버전에서 데이터베이스를 만들 수 있습니다. 일부 데이터를 넣은 다음 runMigrationsAndValidate를 사용하여 수동 마이그레이션 또는 자동 마이그레이션을 검토합니다. 그런 다음 마이그레이션되고 유효성이 검사된 데이터베이스를 얻은 다음 해당 데이터를 확인할 수 있습니다. runMigrationsAndValidate는 자동 마이그레이션도 찾습니다.

아래 링크에서 더 많은 정보를 찾을 수 있습니다.