Realm 모바일 플랫폼에 관심 있는 모바일 개발자들은 마이그레이션에 대한 질문을 자주 합니다. Realm 모바일 플랫폼이 실제로 얼마나 간단하고 직관적인 접근 방법으로 마이그레이션하는지 알려드리겠습니다.
- 스키마 변경은 자동입니다 - 스키마 버전이나 마이그레이션 블럭을 설정하지 않아도 됩니다.
- 스키마 변경은 이전 버전과 호환됩니다 - 기존 클라이언트는 새로운 버전과 계속 동기화됩니다.
- 속성이나 클래스를 추가하거나 제거하는 스키마 변경을 지원합니다.
예제를 통해 자세히 알아보겠습니다. 앱에 하나의 문자열 속성을 가지는 Dog
라는 클래스 하나가 있다고 생각해 볼까요?
class Dog: Object {
dynamic var name = ""
}
class Dog : RealmObject() {
var name = ""
}
public class Dog extends RealmObject {
public String name = "";
// getter / setter
}
앱을 배포한 후 새로운 모델인 Person
을 추가해서 업데이트하고 싶다면 어떻게 할까요? 해당 클래스와 관련 속성을 추가하기만 하면 됩니다.
class Dog: Object {
dynamic var name = ""
dynamic var owner: Person?
}
class Person: Object {
dynamic var name = ""
dynamic var birthdate: NSDate? = nil
}
let syncServerURL = URL(string: "realm://localhost:9080/Dogs")!
// schemaVersion이나 migrationBlock을 설정할 필요가 없습니다
let config = Realm.Configuration(syncConfiguration: SyncConfiguration(user: user, realmURL: syncServerURL))
let realm = try! Realm(configuration: config)
class Dog : RealmObject() {
var name = ""
var owner: Person? = null
}
class Person : RealmObject() {
var name = ""
var birthdate: Date? = null
}
val syncServerURL = "realm://localhost:9080/Dogs"
val config = SyncConfiguration.Builder(user, syncServerURL).build()
val realm = Realm.getInstance(config)
public class Dog extends RealmObject {
private String name = "";
private Person owner;
// getter / setter
}
public class Person extends RealmObject {
private String name = "";
private Date birthdate;
// getter / setter
}
String syncServerURL = "realm://localhost:9080/Dogs"
SyncConfiguration config = new SyncConfiguration.Builder(user, syncServerURL).build();
Realm realm = Realm.getInstance(config);
정말 간단하죠? 이전 버전 사용자는 최신 버전과 계속 동기화되면서 Dog
의 변경 사항만 표시됩니다.
다음으로 Person
에서 생년월일을 제거하는 세 번째 버전을 만들려면 어떻게 할까요?
class Dog: Object {
dynamic var name = ""
dynamic var owner: Person?
}
class Person: Object {
dynamic var name = ""
}
let syncServerURL = URL(string: "realm://localhost:9080/Dogs")!
// schemaVersion이나 migrationBlock을 설정할 필요가 없습니다
let config = Realm.Configuration(syncConfiguration: SyncConfiguration(user: user, realmURL: syncServerURL))
let realm = try! Realm(configuration: config)
class Dog : RealmObject() {
var name = ""
var owner: Person? = null
}
class Person : RealmObject() {
var name = ""
}
val syncServerURL = "realm://localhost:9080/Dogs"
// schemaVersion이나 migrationBlock을 설정할 필요가 없습니다
val config = SyncConfiguration.Builder(user, syncServerURL).build()
val realm = Realm.getInstance(config)
public class Dog extends RealmObject {
private String name = "";
private Person owner;
// getter / setter
}
public class Person extends RealmObject {
private String name = ""
// getter / setter
}
String syncServerURL = "realm://localhost:9080/Dogs"
// schemaVersion이나 migrationBlock을 설정할 필요가 없습니다
SyncConfiguration config = new SyncConfiguration.Builder(user, syncServerURL).build();
Realm realm = Realm.getInstance(config);
이번에도 정말 간단하죠! 내부적으로 Realm은 이전 버전과의 하위 호환성을 유지하기 위해 저장 레이어에 생년월일 열을 계속 유지합니다. 세 번째 버전에 의해 Person
객체가 생성되면 두 번째 버전의 클라이언트는 생년월일에 nil
값을 갖습니다. 옵셔널이 아닌 속성이라면 기본값이 대신 삽입됩니다.
이런 간단한 접근 방식으로 동기 Realm을 여러 버전에서 쉽게 사용할 수 있습니다. 주의할 점은 속성이나 클래스를 추가하거나 제거하는 것은 자동으로 지원되지만, 어떤 스키마 변경 사항은 지원되지 않는다는 것입니다.
- 같은 이름의 속성 타입을 변경하는 경우
- 기본 키를 변경하는 경우
- 속성을 옵셔널에서 필수로, 혹은 필수에서 옵셔널로 변경하는 경우
이런 작업은 이전 버전과 호환되지 않으므로 스키마 변경 사항이 적용된 새로운 동기 Realm을 만들고 필요한 경우 이전 Realm의 데이터를 새 Realm으로 복사해야 합니다.
class Dog: Object {
dynamic var name = ""
dynamic var owner: Person?
}
class Person: Object {
dynamic var name = ""
}
class PersonV2: Object {
dynamic var name: String? = nil
}
var syncServerURL = URL(string: "realm://localhost:9080/Dogs")!
var config = Realm.Configuration(syncConfiguration: SyncConfiguration(user: user, realmURL: syncServerURL))
// 초기 객체 타입 제한
config.objectTypes: [Dog.self, Person.self]
let initialRealm = try! Realm(configuration: config)
syncServerURL = URL(string: "realm://localhost:9080/DogsV2")!
config = Realm.Configuration(syncConfiguration: SyncConfiguration(user: user, realmURL: syncServerURL))
// 새 객체 타입 제한
config.objectTypes: [Dog.self, PersonV2.self]
let newRealm = try! Realm(configuration: config)
class Dog : RealmObject() {
var name = ""
var owner: Person? = null
}
class Person : RealmObject() {
var name = ""
}
class PersonV2 : RealmObject() {
var name = ""
}
@RealmModule(classes = arrayOf(Person::class, Dog::class))
class InitialModule
val syncServerURL = "realm://localhost:9080/Dogs"
val config = SyncConfiguration.Builder(user, syncServerURL)
.modules(InitialModule())
.build()
// 초기 객체 타입 제한
val initialRealm = Realm.getInstance(config)
@RealmModule(classes = arrayOf(Person::class, DogV2::class))
class NewModule
val syncServerURL = "realm://localhost:9080/DogsV2"
val config = SyncConfiguration.Builder(user, syncServerURL)
.modules(InitialModule())
.build()
// 새 객체 타입 제한
val newRealm = Realm.getInstance(config)
public class Dog extends RealmObject {
private String name = "";
private Person owner;
// getter / setter
}
public class Person extends RealmObject {
private String name = "";
// getter / setter
}
public class PersonV2 extends RealmObject {
private String name = "";
// getter / setter
}
@RealmModule(classes = { Person.class, Dog.class }) class InitialModule {}
String syncServerURL = "realm://localhost:9080/Dogs"
SyncConfiguration config = new SyncConfiguration.Builder(user, syncServerURL)
.modules(new InitialModule())
.build();
// 초기 객체 타입 제한
Realm initialRealm = Realm.getInstance(config);
@RealmModule(classes = { Person.class, DogV2.class }) class NewModule {}
String syncServerURL = "realm://localhost:9080/Dogs"
SyncConfiguration config = new SyncConfiguration.Builder(user, syncServerURL)
.modules(new NewModule())
.build();
// 새 객체 타입 제한
Realm initialRealm = Realm.getInstance(config);
컨텐츠에 대하여
이 컨텐츠는 저자의 허가 하에 이곳에서 공유합니다.