Search code examples
c#xamarinrealmrealm-migration

Remove data from old realm during Realm database migration


So I'm in the situation where I need to migrate one of the models in my database. I have added a DateTimeOffset field to the model that will contain a date for my Recommendation model that currently doesn't exist in the database. So there is no way to populate the new field from the existing data.

In my migration callback I want a blank slate for the Recommendation model and all of it's sub models (it's composed of a few classes). So I can fetch a fresh data set of Recommendations from my web-api with the new field. When I attempt to purge the old database of all the existing model data I get an exception.

Realms.Exceptions.RealmInvalidTransactionException

Can't perform transactions on read-only Realms.

How do I achieve the above?

Here's the relevant code for my migration callback.

        var config = new RealmConfiguration("salt.realm");
        config.SchemaVersion = 2;
        config.MigrationCallback = (migration, oldSchemaVersion) =>
        {
            Settings.UpdateDateRecommendationsUtc = DateTime.MinValue;

            migration.OldRealm.Write(() => 
            { 
                migration.OldRealm.RemoveAll("RecDataString");
                migration.OldRealm.RemoveAll("RecChart");
                migration.OldRealm.RemoveAll("RecSummary");
                migration.OldRealm.RemoveAll("RecTickerSymbol");
                migration.OldRealm.RemoveAll("Recommendation");
            });
        };

Solution

  • Since you do not want any data for those five RealmObjects to be preserved during the migration, RemoveAll from the NewRealm as the data will already be available in the NewRealm with either the default values for added properties or missing properties for those that were removed.

    You only need the OldRealm data during the migration if you need to access "old" properties and perform some type of data transformation on it and update the NewRealm with it...

    migration.NewRealm.RemoveAll<POCO>();
    await UpdateRecommendationFromYourWebApi();
    

    Note: Since you are adding a DateTimeOffset, you might want to take note of a current bug that is setting the default value to "1/1/1970 12:00:00 AM +00:00" vs. "1/1/0001 12:00:00 AM +00:00"

    Re: https://github.com/realm/realm-dotnet/issues/1225