정상에서 IT를 외치다

[Android, realm migration] Realm Migration 적용하기 본문

안드로이드

[Android, realm migration] Realm Migration 적용하기

Black-Jin 2018. 9. 14. 13:43
반응형


안녕하세요. 블랙진입니다.


이번시간에는 Realm Migration 적용하기에 대해 포스팅 해보겠습니다.



Migration 이란?


Realm은 모바일에 최적화된 데이터베이스 입니다. 기존에 Realm 을 적용한 앱을 배포한 후 Realm의 데이터를 수정한 후 다시 앱을 업데이트 하게 되면 데이터베이스가 어떻게?! 변경 되었는지를 알려줘야 합니다. 그렇지 않은 경우 여러분의 앱은 


io.realm.exceptions.RealmMigrationNeededException:


에러와 함께 실행중지가 될 겁니다. ㅜㅠ


이때 필요한게 바로 Migration 입니다.


먼저 사용한 예제 파일은 이전에 포스팅 했던 Realm-Diary 를 가지고 하겠습니다. 


Realm 의 기본적인 설명과 사용법에 대한 내용을 다룬 링크입니다. 



Realm Diary


데이터로 사용하는 Person 객체가 있습니다.

사용자를 추가하는 객체로 



PrimaryKey 인 id 와 이름(name), 성별(gender), 나이(age) 그리고 일기 리스트(diaries) 

이렇게 5개의 정보를 가진 객체입니다.




1.  Realm 을 초기화 해주는 부분에서 schemaVersion 설정

// Initialize Realm. Should only be done once when the application starts.
Realm.init(this);

RealmConfiguration config = new RealmConfiguration.Builder()
//.deleteRealmIfMigrationNeeded()
.schemaVersion(1)
.build();

Realm.setDefaultConfiguration(config);

Realm 을 초기화 해주는 부분에서 schemaVersion 을 1로 적용해 줍니다. 


데이터를 수정해 줄 때마다 이 schemeVersion 을 한단계씩 높여야 됩니다.




2.  Persion 객체에 데이터를 추가해 보겠습니다.



보시는 바와 같이 job 이라는 필드를 추가해 줬습니다.

이렇게 한 후 그대로 실행해 보면


io.realm.exceptions.RealmMigrationNeededException: Field count is less than expected - expected 6 but was 5


에러가 발생하며 앱이 죽게됩니다.


내용을 해석해 보면 RealmMigrationNeededException : 기존에 있는 Realm 에서는 필드 개수가 5개였는데 6개로 (job 이 추가 되었으니) 기대되어진다.


추가한 job 필드를 Migrion 을 사용해 알려줘야 됩니다!




3. Migration 추가하기

RealmConfiguration config = new RealmConfiguration.Builder()
//.deleteRealmIfMigrationNeeded()
.schemaVersion(2)
.migration(new RealmMigration() {
@Override
public void migrate(DynamicRealm realm, long oldVersion, long newVersion) {

RealmSchema schema = realm.getSchema();

if(oldVersion == 1) {

RealmObjectSchema mPersonSchema = schema.get("Person");
mPersonSchema.addField("job", String.class, null);
}

}
})
.build();

1) schemaVersion 1 -> 2 로 올려줍니다.


2) migration 을 추가해 줍니다.


기존 앱에 있던 Realm 의 scheamVersion 이 업데이트 후의 scheamVersion과 다르면 최초 1회 migrate 함수가 작동되고 그 뒤에는 작동되지 않습니다.


필드를 추가해 줄때에는 

RealmObjectSchema mPersonSchema = schema.get("Person");
mPersonSchema.addField("job", String.class, null);

Person 객체를 가진 스키마를 불러온 후  job 필드를 추가해줍니다. 


이때 사용한 addField 함수의 파라미터는 아래와 같습니다.

RealmObjectSchema addField(String fieldName, Class<?> fieldType, FieldAttribute... attributes)

필드이름, 필드타입, Attributes 로 3가지 입니다.



- addField


스키마에 필드를 추가해 줄때 아래 이미지와 같이 여러개의 함수가 있습니다. 추가해준 데이터의 타입에 맞춰 addField 를 해주셔야 합니다.




- Attributes


Attributes 또한 아래 이미지와 같이 indexed, required, preimary_key 등 타입에 맞는 형식을 넣어주어야 하며 없는 경우 null 을 입력해 주시면 됩니다.



여기까지 진행해 주셨다면 성공적으로 Person 스키마 job 필드를 추가해 주는데 성공하셨을 겁니다. 짝!짝!짝!


그다음으로는 필드가 아닌 스키마를 새로 추가하는 법에 대해 살펴보겠습니다.






4. 새로운 데이터 클래스 추가하기


이번에는 새로운 스키마를 데이터에 추가해 보겠습니다.


DiaryDetail.class

public class DiaryDetail extends RealmObject {

@Required
private String date;

@Required
private String title;

private String description;
private int number;

}

DiaryDetail 는 위와 같은 4개의 데이터를 가지고 있습니다.


schema.create("DiaryDetail")
.addField("date", String.class, FieldAttribute.REQUIRED)
.addField("title", String.class, FieldAttribute.REQUIRED)
.addField("description", String.class)
.addField("number", int.class);

이때 에는 create 함수를 사용해 스키마를 추가해 줍니다.




5. 총 정리


위 두단계를 모두 적용한 코드를 보여드리겠습니다.


// Initialize Realm. Should only be done once when the application starts.
Realm.init(this);

RealmConfiguration config = new RealmConfiguration.Builder()
//.deleteRealmIfMigrationNeeded()
.schemaVersion(3)
.migration(new RealmMigration() {
@Override
public void migrate(DynamicRealm realm, long oldVersion, long newVersion) {

RealmSchema schema = realm.getSchema();

if(oldVersion == 1) {

RealmObjectSchema mPersonSchema = schema.get("Person");
mPersonSchema.addField("job", String.class);

oldVersion++;
}

if(oldVersion == 2) {

schema.create("DiaryDetail")
.addField("date", String.class, FieldAttribute.REQUIRED)
.addField("title", String.class, FieldAttribute.REQUIRED)
.addField("description", String.class)
.addField("number", int.class);

}

}
})
.build();

Realm.setDefaultConfiguration(config);

위와 같이 Realm 의 스키마 버전 별로 Migration 을 잘 분리해 주셔야 합니다. 또한 데이터 타입을 정확히 맞춰 주어야 에러 없이 Realm 을 업데이트 할 수 있습니다. 


제가 사용한 예제는 아래 링크를 통해 확인해 보실 수 있습니다.


Realm-Diary-Migration




- 개발 단계에서는..


개발 단계에서는 Realm 의 데이터가 달라질때 마다 Migration 을 설정해 주기 매우 불편합니다. 


Realm 의 데이터가 달라지면 기존 데이터를 지우고 새로 만들어주는

deleteRealmIfMigrationNeeded()

을 설정해 주시고 개발하시면 Migration 설정 없이 편리하게 작업하실 수 있을 겁니다.


(대시 업데이트 될 때 마다 기존 Realm 의 데이터는 사라집니다.)




이 외 에도 데이터를 추가, 수정, 삭제 하는 다양한 방법은 아래 깃허브 주소를 보고 확인해 주세요.


Realm Migration git hub




<참고자료>


Realm 에서 Migration 하는 방법

반응형
Comments