Adding PrimaryKey to an area with lots of duplicate data

I need to add @PrimaryKey to two Realm models that are missing due to idiocy. Models are mentioned in several other models through direct relationships or RealmLists, one of the two models also refers to the other model.

My first thought was to rename the schemas in the transfer and copy the data manually, but then Realm complains that the schema is connected in other schemas and cannot be renamed.

Both schemes contain about 15,000 objects that can be compressed to about 100, they are absolutely identical and duplicated due to the lack of @PrimaryKey .

The models themselves are simple:

 class ModelA extends RealmObject { String primaryKey; // Is missing the @PrimaryKey annotation String someField; String someOtherField; Date someDate; ModelB relationToTheOtherProblematicModel; } class ModelB extends RealmObject { String primaryKey; // Is also missing the @PrimaryKey annotation // this class only contains String fields and one Date field } 

How can I transfer data when I add @PrimaryKey to the " primaryKey " field for both classes?

Edit to clarify:

Both circuits contain several completely identical elements.

 primaryKey | someField | someOtherField ------ | ------ | ------ A | foo | bar A | foo | bar A | foo | bar A | foo | bar B | bar | foo B | bar | foo B | bar | foo C | far | boo C | far | boo C | far | boo 

These duplicates can be removed since primaryKey uniquely identifies them. When I add the @PrimaryKey annotation and do the migration, Realm explicitly complains about duplicate values. I need to remove these duplicates without destroying the links in other models.

+6
source share
2 answers

You tried something like this:

 RealmConfiguration config = new RealmConfiguration.Builder(this) .schemaVersion(6) //the new schema version .migration(new RealmMigration() { @Override public void migrate(DynamicRealm realm, long oldVersion, long newVersion) { RealmSchema schema = realm.getSchema(); schema.get("ClassA").addPrimaryKey("primaryKey"); schema.get("ClassB").addPrimaryKey("primaryKey"); } }) .build(); Realm.setDefaultConfiguration(config); 

Edit:
I did the editing based on this . These are the next steps that should solve this:
1. Create a new field, do not mark it as a primary key.
2. Set a new field for a unique value for each instance using transformation
3. Add the index to the new field.
4. Make the new field the primary key.

 RealmConfiguration config = new RealmConfiguration.Builder(this) .schemaVersion(6) //the new schema version .migration(new RealmMigration() { @Override public void migrate(DynamicRealm realm, long oldVersion, long newVersion) { RealmSchema schema = realm.getSchema(); schema.get("ClassA").addField("newKey", String.class) .transform(new RealmObjectSchema.Function() { @Override public void apply(DynamicRealmObject obj) { obj.set("newKey", obj.getString("primaryKey")); } }) .addIndex("newKey") .addPrimaryKey("newKey"); schema.get("ClassB").addField("newKey", String.class) .transform(new RealmObjectSchema.Function() { @Override public void apply(DynamicRealmObject obj) { obj.set("newKey", obj.getString("primaryKey")); } }) .addIndex("newKey") .addPrimaryKey("newKey"); } }) .build(); Realm.setDefaultConfiguration(config); 
0
source

Have you tried to remove duplicate objects before migrating? For example, in your migration class, you can do something like ...

 RealmMigration migration = new RealmMigration() { @Override public void migrate(DynamicRealm realm, long oldVersion, long newVersion) { RealmResults<ModelA> modelAs = realm.where(ModelA.class) .equals("primaryKey", "whatever") .findAll(); for (int i = 1; i < modelAs.size(); i++) { modelAs.get(i).deleteFromRealm(); } // Migration code... if (oldVersion == 1) { ... } } } 

Then you will only have 1 element with each primaryKey, so migration can be performed.

0
source

All Articles