Reputation: 1461
tl;dr: I'm trying to copy every single object from one Realm to another, but I get twice as many objects or 4 times as many objects as I should (because of their relationships, I presume). (Edit: I actually get many many more! Check my last edit at the bottom.)
I'm trying to allow my users to backup and restore their Realm databases.
I have a Book
class and a ReadingSession
class. A Book
can have many ReadingSessions
:
class Book: Object {
// (…)
var readingSessions: [ReadingSession] {
return linkingObjects(ReadingSession.self, forProperty: "book")
}
}
class ReadingSession: Object {
// (…)
var book: Book?
}
To restore from the backup I tried doing this:
func restoreBackupFile(backupFileToRestore: String) {
// (…) I omitted the NSFileManager related part.
let config = Realm.Configuration(path: "\(tmp)/ReadingLog.realm", readOnly: true)
let backupRealm = try! Realm(configuration: config)
let defaultRealm = try! Realm()
let results = backupRealm.objects(Book)
try! defaultRealm.write {
for result in results {
defaultRealm.create(Book.self, value: result)
}
}
That copied all the Book
objects alright, but not the ReadingSessions
related to those Books
.
So I added some code to copy every ReadingSession
too:
// (…)
let bookResults = backupRealm.objects(Book)
let sessionResults = backupRealm.objects(ReadingSession)
try! defaultRealm.write {
for result in bookResults {
defaultRealm.create(Book.self, value: result)
}
for result in sessionResults {
defaultRealm.create(ReadingSession.self, value: result)
}
}
And that gave my defaultRealm
4 times as much books as it should! I used a database with 10 books to test it out, and after running that code my default Realm had 40 books, 20 with the right ReadingSessions
associated to them and 20 without any ReadingSessions
at all.
I tried copying just the ReadingSessions
to see if the related Books
would be created too, and then I got twice as many Books
as I should, half of them with the right ReadingSessions
and half of them without any.
So how can I do what I want? Copy every single object from a Realm to another keeping their relationships intact and without getting duplicates like I am now?
(I know I can just replace the database files, but I want my users to be able to restore data from one database without losing the data from the other.)
Thanks in advance,
Daniel
Edit: I've been experimenting some more and it seems that if I copy just the ReadingSessions
it creates a book for each reading session copied, even if they're related to the same book. If I have a book with 60 reading sessions, for instance, that book will be created 60 times. So my problem is even worse than I thought. When I copy the Books
they don't come with their related ReadingSessions
. When I copy the ReadingSessions
they create many repeated books.
Upvotes: 2
Views: 1067
Reputation: 7806
When you create new objects on base of objects from another Realm, then linked objects are copied as well and recursed into. But backreferences are just convenience getters on your object and neither known to the schema nor accessible (for Swift), so they are not traversed at all. Even though linked objects are recursed into, they are not de-duplicated at all automatically. So this would loop for circular relations.
You might want to configure a primary key on Book
and use create(… update: true)
to copy your ReadingSessions
. When you copy both, you ensure, that unread books are copied as well, if that's a valid case for your schema.
Upvotes: 2