【问题标题】:How to delete Realm while migrating?迁移时如何删除领域?
【发布时间】:2015-09-24 05:43:55
【问题描述】:

这就是我想要的:

public class CustomRealmMigration implements RealmMigration {
    // Current version
    private static final long SCHEMA_VERSION = 4;

    private final Context mContext;

    public CustomRealmMigration(Context context) {
        mContext = context;
    }

    @Override
    public long execute(Realm realm, long version) {
        if (SCHEMA_VERSION < version) {
            // Rollback, not allow
            deleteRealm();
            return SCHEMA_VERSION;
        }
        return version;
    }

    private void deleteRealm() {
        RealmConfiguration realmConfiguration = new RealmConfiguration.Builder(mContext)
                .name(Realm.DEFAULT_REALM_NAME)
                .build();
        Realm.deleteRealm(realmConfiguration);
    }
}

有错误:

Caused by: java.lang.IllegalStateException: It's not allowed to delete the file associated with an open Realm. Remember to close() all the instances of the Realm before deleting its file.

迁移时如何删除 Realm?或者如何在其他地方获取旧版本的 Realm?

【问题讨论】:

    标签: java android migration realm


    【解决方案1】:

    如果您不想在架构更改时迁移数据而只是重置/清除数据库,那么您可以执行以下操作:

    RealmConfiguration realmConfiguration = new RealmConfiguration.Builder(mContext)
                    .name(Realm.DEFAULT_REALM_NAME)
                    .deleteRealmIfMigrationRequired()
                    .build();
    

    这也意味着您不必提供任何迁移代码。

    【讨论】:

    • 如果我当前本地数据库版本高于schemaVersion:Caused by: java.lang.IllegalArgumentException: Realm on disc is newer than the one specified,这种情况我想清空数据库,否则,执行迁移,怎么办?
    • 版本倒退表示语义错误。您的 schemaVersions 永远不应减少,因为这意味着您在新应用程序之上安装了“旧”应用程序。发生这种情况后,您的用例是什么?
    • 我明白了,只是有些设备确实允许用户安装较旧版本的应用程序,所以我想通过使用 Realm 的 API 来避免应用程序强制关闭,如果可能的话......这个要求很奇怪吗?对不起,我只是不知道如何管理它......
    • @ChristianMelchior :我在生产环境中,我认为这可以在我的迁移实现(Realm 版本 0.88.3)中工作:RealmConfiguration config = dynamicRealm.getConfiguration(); dynamicRealm.close(); if (Realm.deleteRealm(config)) DynamicRealm.getInstance(config); 但我收到 RuntimeException:This Realm instance has already been closed, making it unusable. 如何我可以解决这个问题吗? [抱歉格式混乱]​​pan>
    • @ChristianMelchior 在单个领域文件中有多个类。我想删除特定类(表)的所有数据我该怎么做?
    【解决方案2】:
    public class Migration implements RealmMigration {
        @Override
        public long execute(Realm realm, long version) {
    
            /*
                // Version 0
                class Person
                    String firstName;
                    String lastName;
                    int    age;
    
                // Version 1
                class Person
                    String fullName;        // combine firstName and lastName into single field
                    int age;
            */
    
            // Migrate from version 0 to version 1
            if (version == 0) {
                Table personTable = realm.getTable(Person.class);
    
                long fistNameIndex = getIndexForProperty(personTable, "firstName");
                long lastNameIndex = getIndexForProperty(personTable, "lastName");
                long fullNameIndex = personTable.addColumn(ColumnType.STRING, "fullName");
                for (int i = 0; i < personTable.size(); i++) {
                    personTable.setString(fullNameIndex, i, personTable.getString(fistNameIndex, i) + " " +
                            personTable.getString(lastNameIndex, i));
                }
                personTable.removeColumn(getIndexForProperty(personTable, "firstName"));
                personTable.removeColumn(getIndexForProperty(personTable, "lastName"));
                version++;
            }
    
            /*
                // Version 2
                    class Pet                   // add a new model class
                        String name;
                        String type;
    
                    class Person
                        String fullName;
                        int age;
                        RealmList<Pet> pets;    // add an array property
    
            */
            // Migrate from version 1 to version 2
            if (version == 1) {
                Table personTable = realm.getTable(Person.class);
                Table petTable = realm.getTable(Pet.class);
                petTable.addColumn(ColumnType.STRING, "name");
                petTable.addColumn(ColumnType.STRING, "type");
                long petsIndex = personTable.addColumnLink(ColumnType.LINK_LIST, "pets", petTable);
                long fullNameIndex = getIndexForProperty(personTable, "fullName");
    
                for (int i = 0; i < personTable.size(); i++) {
                    if (personTable.getString(fullNameIndex, i).equals("JP McDonald")) {
                        personTable.getUncheckedRow(i).getLinkList(petsIndex).add(petTable.add("Jimbo", "dog"));
                    }
                }
                version++;
            }
    
            /*
                // Version 3
                    class Pet
                        String name;
                        int type;               // type becomes int
    
                    class Person
                        String fullName;
                        RealmList<Pet> pets;    // age and pets re-ordered
                        int age;
            */
            // Migrate from version 2 to version 3
            if (version == 2) {
                Table petTable = realm.getTable(Pet.class);
                long oldTypeIndex = getIndexForProperty(petTable, "type");
                long typeIndex = petTable.addColumn(ColumnType.INTEGER, "type");
                for (int i = 0; i < petTable.size(); i++) {
                    String type = petTable.getString(oldTypeIndex, i);
                    if (type.equals("dog")) {
                        petTable.setLong(typeIndex, i, 1);
                    }
                    else if (type.equals("cat")) {
                        petTable.setLong(typeIndex, i, 2);
                    }
                    else if (type.equals("hamster")) {
                        petTable.setLong(typeIndex, i, 3);
                    }
                }
                petTable.removeColumn(oldTypeIndex);
                version++;
            }
            return version;
        }
    
        private long getIndexForProperty(Table table, String name) {
            for (int i = 0; i < table.getColumnCount(); i++) {
                if (table.getColumnName(i).equals(name)) {
                    return i;
                }
            }
            return -1;
        }
    }
    
    
    
    And in Activity 
    
     copyBundledRealmFile(this.getResources().openRawResource(R.raw.default0), "default0");
            copyBundledRealmFile(this.getResources().openRawResource(R.raw.default1), "default1");
            copyBundledRealmFile(this.getResources().openRawResource(R.raw.default2), "default2");
    
            // When you create a RealmConfiguration you can specify the version of the schema.
            // If the schema does not have that version a RealmMigrationNeededException will be thrown.
            RealmConfiguration config0 = new RealmConfiguration.Builder(this)
                    .name("default0")
                    .schemaVersion(3)
                    .build();
    
            // You can then manually call Realm.migrateRealm().
            Realm.migrateRealm(config0, new Migration());
            realm = Realm.getInstance(config0);
            showStatus("Default0");
            showStatus(realm);
            realm.close();
    
            // Or you can add the migration code to the configuration. This will run the migration code without throwing
            // a RealmMigrationNeededException.
            RealmConfiguration config1 = new RealmConfiguration.Builder(this)
                    .name("default1")
                    .schemaVersion(3)
                    .migration(new Migration())
                    .build();
    
            realm = Realm.getInstance(config1); // Automatically run migration if needed
            showStatus("Default1");
            showStatus(realm);
            realm.close();
    
            // or you can set .deleteRealmIfMigrationNeeded() if you don't want to bother with migrations.
            // WARNING: This will delete all data in the Realm though.
            RealmConfiguration config2 = new RealmConfiguration.Builder(this)
                    .name("default2")
                    .schemaVersion(3)
                    .deleteRealmIfMigrationNeeded()
                    .build();
    
            realm = Realm.getInstance(config2);
            showStatus("default2");
            showStatus(realm);
            realm.close();
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2022-06-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多