Navigation

Migrations

Overview

A migration transforms an existing realm and its objects from its current Realm Schema version to a newer one. Application data models typically change over time to accommodate new requirements and features. Migrations give you the flexibility to automatically update your existing application data whenever a client application upgrades to a newer version.

Key Concepts

Local Migration

A local migration is a migration for a realm that does not automatically Sync with another realm. Local migrations have access to the existing Realm Schema, version, and objects and define logic that incrementally updates the realm to its new schema version. To perform a local migration you must specify a new schema version that is higher than the current version and provide a migration function when you open the out-of-date realm.

MongoDB Realm automatically migrates certain changes, such as new and deleted properties, but does not automatically set values for new properties unless the updated object schema specifies a default value. You can define additional logic in the migration that dynamically calculates a new property’s value. Migrations do not allow you to directly rename a property. Instead, it treats a renamed property as a new property that you must set to the value of the old property before MongoDB Realm automatically deletes it.

Example

A realm using schema version 1 has a Person object type:

class Person: RealmObject {
    var firstName: String = ""
    var lastName: String = ""
    var age: int = 0
}
public class Person extends RealmObject {
    @Required
    public String firstName;
    @Required
    public String lastName;
    @Required
    public int age;
}

The developer decides that the Person class should use a combined fullName field instead of the separate firstName and lastName fields:

class Person: RealmObject {
    var fullName: String = ""
    var age: int = 0
}
public class Person extends RealmObject {
    @Required
    public String fullName;
    @Required
    public int age;
}

To migrate the realm to conform to the updated Person schema, the developer sets the realm’s schema version to 2 and defines a migration function to set the value of fullName based on the existing firstName and lastName properties:

public class Migration implements RealmMigration {
  @Override
  public void migrate(DynamicRealm realm, long oldVersion, long newVersion) {
  
     // DynamicRealm exposes an editable schema
     RealmSchema schema = realm.getSchema();
     
     if (oldVersion == 1) {
        schema.create("Person")
            .addField("fullName", String.class)
            .addField("age", int.class);
        
        realm.beginTransaction();
        for (Person person : realm.where(Person.class).findAll()) {
            person["fullName"] = person["firstName"] + " " + person["lastName"];
        }
        realm.commitTransaction();
        
        oldVersion++;
     }
  }
};

@RealmModule(classes = { Person.class })
public class Module {}

RealmConfiguration config = new RealmConfiguration.Builder()
    .modules(new Module())
    .schemaVersion(2) // Must be bumped when the schema changes
    .migration(new Migration()) // Migration to run instead of throwing an exception
    .build();
public class Migration implements RealmMigration {
  @Override
  public void migrate(DynamicRealm realm, long oldVersion, long newVersion) {

     // DynamicRealm exposes an editable schema
     RealmSchema schema = realm.getSchema();
     
     if (oldVersion == 1) {
        schema.create("Person")
            .addField("fullName", String.class)
            .addField("age", int.class);
        
        realm.beginTransaction();
        for (Person person : realm.where(Person.class).findAll()) {
            person["fullName"] = person["firstName"] + " " + person["lastName"];
        }
        realm.commitTransaction();

        oldVersion++;
     }
  }
};

@RealmModule(classes = { Person.class })
public class Module {}

RealmConfiguration config = new RealmConfiguration.Builder()
    .modules(new Module())
    .schemaVersion(2) // Must be bumped when the schema changes
    .migration(new Migration()) // Migration to run instead of throwing an exception
    .build();

Synced Migration

A synced migration is a migration for a realm that automatically Syncs with another remote realm. Realm Database automatically handles all synced schema migrations and does not allow you to specify a migration function.

Synced realms represent multiple end users and devices that will likely not all immediately update to the most recent version of an application. MongoDB Realm ensures that synced schema changes are backwards compatible, which means that client applications that have not updated to the most recent version can still sync with clients that are using the most recent version.

MongoDB Realm handles synced migrations using the following framework:

Change Type Description
Schema Version MongoDB Realm ignores any schema version set by the client application.
Migration Function MongoDB Realm throws an error if the realm configuration includes a local migration function.
Additions MongoDB Realm automatically applies additive changes, such as a new class or class property.
Deletions

MongoDB Realm does not delete removed fields from the database, but ignores them in future read operations. MongoDB Realm includes deleted properties in new objects with a default value that depends on whether or not the property was required:

  • MongoDB Realm sets the value of optional deleted properties to null.
  • MongoDB Realm sets the value of required deleted properties to the empty value of the property type (e.g. 0 for numeric fields, "" for string properties, etc.).
Modifications

MongoDB Realm prevents modifications to an existing property other than delete operations. Modifications that synced realms do not support include:

  • Changing a property’s type but keeping the same name.
  • Changing an object type’s primary key.
  • Changing a property from optional to required (or vice-versa).

Summary

  • A migration transforms an existing realm and its objects from its current schema version to a later one.
  • MongoDB Realm allows you to specify migration functions for local migrations, i.e. migrations where the realm is not synced with MongoDB Realm.
  • MongoDB Realm automatically handles synced migration, i.e. migrations where the realm is synced. MongoDB Realm does not allow migration functions for such migrations.