【问题标题】:How to do a Realm migration in Android?如何在 Android 中进行 Realm 迁移?
【发布时间】:2018-05-16 08:44:40
【问题描述】:

我在 Android 应用程序中使用 Realms 作为数据库。工作正常,但我在我的用户模型中添加了一个新标签,我收到了我需要迁移我的架构的错误:

java.lang.RuntimeException: Unable to create application com.apelucy.apelucy.app.base.MyApplication: io.realm.exceptions.RealmMigrationNeededException: Migration is required due to the following errors:
                                                   - Property 'User.testRealm' has been added.

如何进行迁移?我在这里找到了其他解决方案,但我无法在我的代码中实现它们。我无法使用删除和安装应用程序的解决方案。我现在从事开发工作,但我需要更新生产中的应用程序。

我的 UserRespository 类:

public class UserRepository {

    private static UserRepository sInstance = null;
    private Context mContext = null;



    public static UserRepository getInstance(Context context) {
        if (sInstance == null) {
            sInstance = new UserRepository();
            sInstance.mContext = context;
        }

        return sInstance;
    }

    // DATABASE Methods

    public void storeUser(final User user) {
        AppSingleton.getInstance().setUser(user);

        Realm realm = null;
        try {
            realm = Realm.getDefaultInstance();
            realm.executeTransaction(realm1 -> realm1.insertOrUpdate(user));
        } finally {
            if (realm != null) {
                realm.close();
            }
        }
    }

    public User retrieveUser() {
        Realm realm = null;
        User user = null;
        try {
            realm = Realm.getDefaultInstance();
            User userRealmResult = realm.where(User.class)
                    .findFirst();

            if (userRealmResult != null) {
                user = realm.copyFromRealm(userRealmResult);
            }

        } finally {
            if (realm != null) {
                realm.close();
            }
        }

        return user;
    }

    public void clearUser() {
        // Clear Database objects
        Realm realm = null;
        try {
            realm = Realm.getDefaultInstance();
            realm.executeTransaction(realm1 -> realm1.delete(User.class));
        } finally {
            if (realm != null) {
                realm.close();
            }
        }
    }
}

在我的应用程序中初始化领域:

Realm.init(this);

我的模型改变:

@SerializedName("test")
@Expose
private String testRealm;

【问题讨论】:

  • 有一个迁移文档realm.io/docs/java/latest/#migrations,它也有一个示例应用程序。你试过了吗?
  • 是的,我已经尝试过使用这个文档,但我做不到
  • 我认为您应该发布您已经为迁移所做的代码以及您遇到的错误。然后我们可以帮助您更轻松。我很确定遵循文档和示例可以帮助您申请迁移,因为我曾经这样做过
  • 实际上,我已经添加了 Eirini 的答案,是的,可以正常工作而不会导致应用程序崩溃。但是,如果可能的话,我也想保留数据
  • 是的,有可能github.com/realm/realm-java/blob/master/examples/…。另外我认为总是deleteRealmIfMigrationNeeded 不适合生产应用程序

标签: android realm


【解决方案1】:

迁移允许您修改应用程序的架构,这意味着它允许您在领域架构中添加、删除、重命名表/字段。如果您更改 RealmModel 类,那么您必须编写将映射现有 Realm 文件以反映新模型类的迁移。

RealmConfiguration config = new RealmConfiguration.Builder()
                                 .schemaVersion(1)
                                 .migration(new MyMigration()) 
                                 .build();
Realm.setDefaultConfiguration(config);

默认架构版本为 0。


迁移相当简单:

  • 您必须增加架构版本,以便 Realm 知道您要将架构的版本增加到特定数字

  • 您必须提供一个迁移来处理从一个版本到另一个版本的更改

迁移描述了当您需要从一个架构版本转到另一个架构版本时要执行的操作:

public class MyMigration implements RealmMigration {

    @Override
    public void migrate(final DynamicRealm realm, long oldVersion, long newVersion) {
        RealmSchema schema = realm.getSchema();

        // Migrate from version 0 to version 1
        if (oldVersion == 0) {
            RealmObjectSchema userSchema = schema.get("User");

            userSchema.addField("testRealm", String.class);
            oldVersion++;
        }

        if (oldVersion == 1) { // ...
            // ...
        }
    }

    @Override
    public int hashCode() { return MyMigration.class.hashCode(); }

    @Override
    public boolean equals(Object object) { return object != null && object instanceof MyMigration; }
}

【讨论】:

  • 不要忘记将 Migration 类包含到配置构建器中
  • 你是对的,这是一个完整答案的好主意
【解决方案2】:

将此添加到您的应用程序文件中。如果您将新表添加到列,这将 Realm 删除所有内容。

RealmConfiguration config = new RealmConfiguration.Builder().name("dbname.realm")
                                     .deleteRealmIfMigrationNeeded()
                                     .build();
Realm.setDefaultConfiguration(config);

【讨论】:

  • 是的,但是......有什么解决方案可以在不删除所有数据的情况下进行迁移吗?
  • 删除所有数据以重新开始不被视为迁移
  • 他特意说不想删除所有数据。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-04-24
  • 2020-05-31
  • 1970-01-01
  • 2011-01-30
相关资源
最近更新 更多