realm / realm-swift

Realm is a mobile database: a replacement for Core Data & SQLite
https://realm.io
Apache License 2.0
16.32k stars 2.15k forks source link

Add support for cascading deletes #1186

Open alazier opened 9 years ago

alazier commented 9 years ago

Blocked on support in core.

martheli commented 6 years ago

Any update on cascading delete feature?

Zhuinden commented 6 years ago

I've heard that once Realm Core 6 is in, then cascade deletion will be added afterwards too

bmunkholm commented 6 years ago

Outside of Core6 upgrade the biggest blocker for cascading deletes is to make support for that with sync. That's a bit tricky, and we currently don't have a committed timeframe for that, unfortunately. But this issue will surely be updated ones we have more info.

chkkassd commented 6 years ago

Any update on this issue?

Zhuinden commented 6 years ago

Or it could be supported for non-sync Realms only until Sync supports it :smile:

bsrz commented 6 years ago

Almost 4 years since the opening of this issue. For a feature that comes built-in with CoreData. It's kind of disappointing that Realm isn't making this a priority. Slowly moving away from Realm because of this.

VladimirMitin commented 6 years ago

Almost 4 years since the opening of this issue. For a feature that comes built-in with CoreData. It's kind of disappointing that Realm isn't making this a priority. Slowly moving away from Realm because of this.

Me too.

rayflection commented 5 years ago

Sybase has cascading delete triggers 30 years ago. Just sayin'.

jaltin commented 5 years ago

Is there any news on the implementation of this feature?

ivnsch commented 5 years ago

Also very disappointed that this hasn't been implemented so far. I released my app and have had several complaints already about db being inaccessible (corrupted) so the app has to be removed and reinstalled. I try to ensure consistency by doing everything manually (cascade deletes, foreign keys, semantic uniques, migration from local to synced realm) but this is (evidently) far from ideal. This is basic functionality that the database should provide out of the box. Realm is very fragile and gets in an inconsistent state easily, resulting in unusable apps. Please improve this.

ariantomichael commented 5 years ago

bump

keshavkishore09 commented 5 years ago

Implemented Realm in my whole app, didn't know we would be encountering this issue at earliest. Creating hell lot of problem to manage the objects. How soon we will have this feature?

o15a3d4l11s2 commented 5 years ago

@keshavkishore09, we are also waiting for the feature, but in the meantime there are enough solutions that can solve your problem until they release the cascade deletion. Check the answers above. To sum it up: what we did was extend the realm models with a new method that returns the properties/objects that should be cascade-deleted. Then for each such property/object we do the same until all is deleted.

effzehn commented 5 years ago

The PR for this feature is open since June 2018. This issue is being discussed since 2014. Make of that what you will, but at this point you should think about your in-house solution like many other people in this thread did.

bmunkholm commented 5 years ago

I'm not assuming this will help anyone, but I can at least spread a bit of light over our thinking. I can confirm that we are going to do this. It is "just" a matter of time and resources. So far we have not prioritized it high as there are workarounds, and we have focused on other bugs and features without workarounds. That's of course not useful for anyone wanting this feature. But this is one of the top features we want to add once we have rolled out Core6, which we are now actively working on again. As for timing, my best guess (as plans looks right now) is that it won't make it this year, but early next year. We appreciate all your patience with this and understand the impatience...

ZsoltMolnarrr commented 4 years ago

Hello! Can we have some update please? While we wait for official support, can any of the contributors points towards a suggested workaround? For example is this solution correct https://gist.github.com/verebes1/02950e46fff91456f2ad359b3f3ec3d9 ?

bmunkholm commented 4 years ago

I can give a quick update. As you may have seen we have released a beta with Core6 and Frozen Objects (do try it out!) and expect the GA version in April. We are currently implementing " Embedded Objects" that will give you a similar functionality if it fits your data models. But it won't help you much for highly linked data models where you can't just embed one model in another. That is still something we will look into prioritizing this year.

sergstav commented 3 years ago

@bmunkholm Hello, can we give some updates on this?

bmunkholm commented 3 years ago

Embedded Objects was released a while back and would enable the cascading delete semantics in most cases. Have you looked at that?

sergstav commented 3 years ago

@bmunkholm oh, no, sorry. Thank you for quick response! Can you suggest on which version Embedded Objects was released?

sergstav commented 3 years ago

@bmunkholm ok, I found it.

bdkjones commented 3 years ago

Is embeddedObject the end of the story here? This blog post makes it sound like Realm thinks Cascading Deletes are now a solved problem: https://developer.mongodb.com/article/realm-database-cascading-deletes/

But...they aren't. The limitation that EmbeddedObject can't be queried directly makes them far less useful. And other object-graph frameworks such as Core Data (which is what I'm coming from) don't have this limitation. So I'm trying to understand if this issue is still open and being worked on, or if EmbeddedObject is the end of it.

It's also possible I don't understand Realm's performance. Suppose I have:

final class Parent: Object
{
    let kids: List<Child> = List()
}

final class Child: EmbeddedObject
{
    let linkedParents: LinkingObjects<Parent> = LinkingObjects(fromType: Parent.self, property: "kids")
    @objc dynamic var foo: String = "some string"
}

Suppose I have 2,600,000 Parent objects, each with a few Child objects. Is it really going to be performant to run realm.objects(Parent.self)..., and then filter to find the ONE Child object with a particular value of foo?

That can't be as fast as directly querying for the Child where foo == someValue, can it?

tgoyne commented 3 years ago

More and better cascading delete functionality is still on the roadmap, although not in the immediate future. We think embedded objects cover many of the cases where people want cascading deletes, but they definitely don't cover anything.

WRT to the second half of your question, the best you can do currently is probably:

for parent in realm.objects(Parent.self).filter("ANY kids.foo = %@", someValue) {
    for child in parent.kids.filter("foo = %@", someValue) {
        // ...
    }
}

This is typically going to be significantly slower than Querying Child directly would be

bdkjones commented 3 years ago

In my case, Child is just a wrapper with one string property, foo. (I did this because Realm didn’t appear to allow queries against List<String>, although that seems to be outdated information now?)

If I abandoned the Child objects and instead used:

class Parent: Object
{
    let foo: List<String> = List()
}

Would this query be reasonably the same performance as querying a Child wrapper object? —>

realm.objects(Parent.self).filter(NSPredicate(format: “%@ IN[c] foo“, someStringValue)

(Thanks for the guidance. It’s just very expensive in terms of dev time to try different approaches and profile them; I’m hoping your experience can point me down the best path.)

tgoyne commented 3 years ago

We don't support using IN in that way, but I'm guessing that ANY foo ==[c] %@ is what you want (it is the same operation as IN with a constant value on the lhs and a property on the rhs would be if we supported that). How it compares performance-wise to querying Child and then getting the parent objects via LinkingObjects depends on what the ratio of Parent to Child objects is. If you have a small set of Child objects which are each linked to by a very large number of Parents, then querying Child will be much faster. This is because accessing a LinkingObjects object just reads a persisted data structure and doesn't have to do a table scan on Parent.

If each Child object has exactly one parent, or if there's more Child objects than Parent objects, then querying via a List on the parent should be a bit faster than either a query on the value over the link or a query on Child and looking up the parent from that.

bdkjones commented 3 years ago

@tgoyne Thanks! In my case, the vast majority of Parent objects will have exactly one String in foo: List<String> and only a few will have multiple Strings in the list.

(The list items are filepaths. Most Parent objects have one filepath on disk, but a few have multiple paths to duplicate files.)

It sounds like

realm.objects(Parent.self).filter(NSPredicate(format: “ANY foo ==[c] %@“, someStringValue)

should be performant, without needing the wrapper Child objects that I can’t query if they’re embedded. The List of Strings solves the problem with cascading deletes for me.

tgoyne commented 3 years ago

Yep, for that it sounds like a List<String> is exactly what you want now that we finally support querying those.