[英]Android Realm.io migration: Fallback to .deleteRealmIfMigrationNeeded()
When migrating an Android Realm.io instance to a newer schema I provide migration steps in my Migration implementation: 将Android Realm.io实例迁移到较新的架构时,我在“迁移”实现中提供了迁移步骤:
RealmConfiguration config = new RealmConfiguration
.Builder(this)
.schemaVersion(SCHEMA_VERSION)
.migration(new Migration())
.build();
What I want to do in the actual migration code I want to fallback to deleteRealmIfMigrationNeeded
for older schema versions. 我想在实际的迁移代码中执行的操作,我想回退以
deleteRealmIfMigrationNeeded
较旧的架构版本的deleteRealmIfMigrationNeeded
。
Is there any way to do that? 有什么办法吗? I tried to do it with
deleteAll()
but that doesn't seem to work as some people updating from an older version of the app are getting Realm validation errors. 我尝试使用
deleteAll()
来执行此操作,但由于某些从旧版应用程序进行更新的人遇到了Realm验证错误,因此该方法似乎不起作用。
public class Migration implements RealmMigration {
@Override
public void migrate(DynamicRealm realm, long oldVersion, long newVersion) {
if (oldVersion < 105) {
realm.deleteAll();
return;
}
//handle newer schema versions
}
}
You can try to open a Realm in dynamic mode and ask for it's version. 您可以尝试以动态模式打开领域并询问其版本。 DynamicRealms will not trigger migrations:
DynamicRealms不会触发迁移:
RealmConfiguration config = new RealmConfiguration
.Builder(this)
.schemaVersion(SCHEMA_VERSION)
.migration(new Migration())
.build();
// Use DynamicRealm to find version and delete it if it is too old
DynamicRealm dRealm = DynamicRealm.getInstance(config);
boolean delete = dRealm.getVersion() < 42;
dRealm.close();
if (delete) {
Realm.deleteRealm(config);
}
Realm realm = Realm.getInstance(config);
To clear the classes within the migration, you can remove all the classes that are within the Realm, and then restore classes using the same methodology that Realm uses: 要清除迁移中的类,您可以删除Realm中的所有类,然后使用与Realm使用相同的方法还原类:
package io.realm;
public class Migration implements RealmMigration {
@Override
public void migrate(DynamicRealm realm, long oldVersion, long newVersion) {
RealmConfiguration configuration = realm.getConfiguration();
if(oldVersion < 105) {
RealmSchema schema = realm.getSchema();
Set<RealmObjectSchema> classSchemas = schema.getAll();
for(RealmObjectSchema classSchema : classSchemas) {
schema.remove(classSchema.getClassName());
}
}
Set<Class<? extends RealmModel>> currentModels = configuration.getRealmObjectClasses();
Set<Class<? extends RealmModel>> nonExistentModels = new HashSet<>();
for(Class<?> clazz : currentModels) {
if(!schema.contains(clazz.getCanonicalName()) {
nonExistentModels.put(clazz);
} else {
// TODO: migrate current classes that do exist
}
}
for(Class<?> nonExistentClazz : nonExistentModels) {
// partly taken from Realm 1.1.1's Realm.java : initializeRealm(Realm) method
RealmProxyMediator mediator = configuration.getSchemaMediator(); // package internal
mediator.createTable(modelClass, realm.sharedGroupManager.getTransaction()); // package internal
}
}
}
Although to be fair, this uses package-internal magic and Christian Melchior's answer is simpler, and doesn't rely on such magical things. 尽管很公平,但这使用了内部打包魔术,克里斯蒂安·梅尔基奥尔的回答更简单,并且不依赖于此类魔术。
Also, I wrote it directly here, so I haven't actually ran it. 另外,我直接在这里写的,所以我实际上还没有运行过。
How about something to the effect of: 效果如何:
final RealmConfiguration.Builder builder=new RealmConfiguration.Builder(this);
builder.schemaVersion(SCHEMA_VERSION);
if (SCHEMA_VERSION < 105) {
builder.deleteRealmIfMigrationNeeded();
} else {
builder.migration(new Migration());
}
final RealmConfiguration config = builder.build();
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.