How to efficiently update a field from all objects with random values

163 views
Skip to first unread message

Ivan Schuetz

unread,
Apr 11, 2016, 6:36:53 PM4/11/16
to Realm
Hi,

I have to replace the uuids of an unfiltered group of objects. All realm.objects(MyObj) need a new uuid.

What is the best way to do this? So far I'm seeing I'll have to load all the objects to do this update? Since loading is lazy I think this may not be a big deal but it's still quite a lot of objects and I wonder if there's a better way.

Thanks,
Ivan


Ivan Schuetz

unread,
Apr 11, 2016, 8:10:53 PM4/11/16
to Realm
Actually, the problem is a bit worser since it doesn't seem to be possible to change the objects primary keys. Ideas?

To give some context, I want to ship some prefilled database as part of an app. All the objects have uuids. The problem is that the app can (optionally) connect at some point with the server, and I need that the uuids, are, well, unique, also in the server. If I let the uuids of the prefilled database unchanged, these uuids will be the same in all clients and there will be errors on sync. So as a solution I thought I'd re-generate the uuids at runtime after the database is copied.

Ivan Schuetz

unread,
Apr 11, 2016, 8:15:10 PM4/11/16
to Realm
I could instead of copying the realm just open it and copy the entries one by one assigning a new uuid? Is this the only way? I feel I'm missing something. If it's the only way how do I do it?

Ivan Schuetz

unread,
Apr 11, 2016, 8:18:14 PM4/11/16
to Realm
Alternatively (sorry for spamming, this is the last one...) the unique in the server could be set to uuid+user-uuid I think this could work but it feels not correct, since uuids should be unique.

Ivan Schuetz

unread,
Apr 12, 2016, 7:55:29 AM4/12/16
to Marius Rackwitz, realm...@googlegroups.com
Hi Marius,

thanks. It crashes though when setting the uuid: "Primary key can't be changed after an object is inserted.". How can I get around this?



2016-04-12 11:36 GMT+02:00 Marius Rackwitz <he...@realm.io>:
The best way would likely opening the bundled prefilled database as read-only.
You can then retrieve all the objects, iterate over them and assign each a new UUID and add them to the Realm.

let resourcePath = NSBundle.mainBundle().resourcePath as NSString?
let readonlyRealmPath = resourcePath!.stringByAppendingPathComponent(“default.realm”)
let readonlyRealm = try! Realm(path: readonlyRealmPath)

let realm = try! Realm()

var objects = readonlyRealm.objects(MyObj)
for object in objects {
     object.uuid = NSUUID().UUIDString
     realm.create(MyObj.self, value: object)
}


--
Marius Rackwitz
iOS Product Engineer
{#HS:191114076-3758#}
--
You received this message because you are subscribed to the Google Groups "Realm" group.
To unsubscribe from this group and stop receiving emails from it, send an email to realm-cocoa...@googlegroups.com.
To post to this group, send email to realm...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/realm-cocoa/111fc38f-6563-44be-a37d-6f33d68bce73%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.




Ivan Schuetz

unread,
Apr 12, 2016, 8:01:19 AM4/12/16
to Marius Rackwitz, realm...@googlegroups.com
I could create new instances and copy all the fields from the read only object but this means everything is loaded into memory. Maybe there's a better way?

Ivan Schuetz

unread,
Apr 12, 2016, 8:06:45 AM4/12/16
to Marius Rackwitz, realm...@googlegroups.com
Ah, just received your message. Will do it like this then if it's the only way. Btw what is the difference between using a dictionary/create and initialising new database objects/add?

Ivan Schuetz

unread,
Apr 12, 2016, 8:45:09 AM4/12/16
to Marius Rackwitz, realm...@googlegroups.com
I just noticed another problem. I have 2 prefill types A and B, A has B as a linked property. Since I'm creating new instances of B it looks like I have to update A to reference these new instances. So I'd have probably to create a look up dictionary of the new Bs to retrieve them while creating the A instances/dictionaries.

I wonder if I maybe should ship the prefill database in code rather than as a Realm. The reason I used the Realm was the performance benefit of just having to copy the file, but now it seems that, since I have to load it and iterate through all the entries the performance may be worser and this lookup makes the code also more complex.

2016-04-12 14:35 GMT+02:00 Marius Rackwitz <he...@realm.io>:
Both alternatives are functionality equivalent. Dictionaries may make it easier in some cases to apply dynamic programming strategies (e.g. iterating over all properties) while unattached objects can help to to enforce the correct types. Beside that dictionaries can be used to describe only the primary key and new attributes on update, but that doesn't help here.


--
Marius Rackwitz
iOS Product Engineer
{#HS:191114076-3758#}
On Tue, Apr 12, 2016 at 12:06 PM UTC, Ivan Schuetz <ivans...@gmail.com> wrote:
Ah, just received your message. Will do it like this then if it's the only way. Btw what is the difference between using a dictionary/create and initialising new database objects/add?



On Tue, Apr 12, 2016 at 12:01 PM UTC, Ivan Schuetz <ivans...@gmail.com> wrote:
I could create new instances and copy all the fields from the read only object but this means everything is loaded into memory. Maybe there's a better way?



On Tue, Apr 12, 2016 at 12:00 PM UTC, Marius Rackwitz <he...@realm.io> wrote:
Oops! Totally missed that when writing the sample code.
You will need to create instead a modified intermediate representation of the object in memory.
That could be for example a dictionary, which you can directly pass to Realm#create.

dict = [
  "uuid": NSUUID().UUIDString,
  "propA": object.propA,
  "propB": object.propB,
]
realm.create(MyObj.self, value: dict)


Ivan Schuetz

unread,
Apr 12, 2016, 9:22:23 AM4/12/16
to Marius Rackwitz, realm...@googlegroups.com
Ok, I'll ship it as code. This also seems to be better for internationalisation. Thanks for your help!

2016-04-12 14:57 GMT+02:00 Marius Rackwitz <he...@realm.io>:
It really depends on the structure of your data and how much modifications, you would need to make.
But if shipping the code you use to generate the prefilled database is an option, that would slim down the resulting app size and so also beneficial to your users in that way.


--
Marius Rackwitz
iOS Product Engineer
{#HS:191114076-3758#}
On Tue, Apr 12, 2016 at 12:45 PM UTC, Ivan Schuetz <ivans...@gmail.com> wrote:
I just noticed another problem. I have 2 prefill types A and B, A has B as a linked property. Since I'm creating new instances of B it looks like I have to update A to reference these new instances. So I'd have probably to create a look up dictionary of the new Bs to retrieve them while creating the A instances/dictionaries.

I wonder if I maybe should ship the prefill database in code rather than as a Realm. The reason I used the Realm was the performance benefit of just having to copy the file, but now it seems that, since I have to load it and iterate through all the entries the performance may be worser and this lookup makes the code also more complex.



On Tue, Apr 12, 2016 at 12:34 PM UTC, Marius Rackwitz <he...@realm.io> wrote:
Both alternatives are functionality equivalent. Dictionaries may make it easier in some cases to apply dynamic programming strategies (e.g. iterating over all properties) while unattached objects can help to to enforce the correct types. Beside that dictionaries can be used to describe only the primary key and new attributes on update, but that doesn't help here.

--
Marius Rackwitz
iOS Product Engineer


Reply all
Reply to author
Forward
0 new messages