- changed milestone to 0.7.xx
Automatic expiration of related properties (objects or collections), i.e. when the FK attribute changes. you know, this thing.
http://www.sqlalchemy.org/trac/ticket/1910#comment:5
When the sqla detects a change in an attribute which is included in the relationship()
join, it can automatically expire the property of that relationship
.
Bear in mind, some joins are manually specified, so these wouldn't necessarily be fks. I think it is sufficient that if the attribute that is changing is included anywhere in the join, the expiration should take place. This leaves some flexibility for mapper joins that are manually specified.
Comments (18)
-
repo owner -
Account Deleted Mike, I implemented a limited case of this functionality with an
AttributeExtension
.
def set(self,...)
decides which relations to expire based on whether any properties exist with self's attribute name in(l.key for (l, r) in prop.local_remote_pairs)
.I have a question. It is possible that a part of the related object which we are about to expire has unflushed changes. It is also possible that autoflush has been disabled. Any thoughts on how you'd deal with these circumstances? I looked into session.is_modified(), but it doesn't detect a change in a related object, nor would attributes.get_history(obj, 'relatedproperty')...
Thanks very much, as always, Kent
-
repo owner By "unflushed changes", are you referring to the case when the FK attributes have been changed, and there are also changes to the relationship() reference itself ? Well yes that's why I am in no hurry to implement this feature. If they have autoflush off, they modified relationship(), then they went and set the FKs to something that is in conflict with relationship, with this new change the FKs win - or better yet we could raise an error if changes are detected on the relationship. Why would attributes.get_history() not work for checking a pending change ?
-
Account Deleted Replying to zzzeek:
By "unflushed changes", are you referring to the case when the FK attributes have been changed, and there are also changes to the relationship() reference itself ?
Yes, exactly
Well yes that's why I am in no hurry to implement this feature. If they have autoflush off, they modified relationship(), then they went and set the FKs to something that is in conflict with relationship, with this new change the FKs win - or better yet we could raise an error if changes are detected on the relationship.
Yeah, that might be the best, my brick wall was even detecting it
Why would attributes.get_history() not work for checking a pending change ?
I suppose it ''could'', but I'd have to recursively check all it's relations for changes as well, wouldn't I? In other words,
attributes.get_history(obj,'related')
only tells me if 'related' has been changed to a new object, None, etc, but it doesn't tell me whether it ''itself'' has changes. Is there such a library function already written that searches the save/update cascade of a given object for changes? -
repo owner I dont think you need to check if the related object "itself" has changes - we're only talking about the linkage between parent and child object. The two objects are still in the session and changes they have which are not related to that linkage are handled independently.
-
Account Deleted Replying to zzzeek:
I dont think you need to check if the related object "itself" has changes - we're only talking about the linkage between parent and child object. The two objects are still in the session and changes they have which are not related to that linkage are handled independently.
Oh good. Much simpler then.
-
repo owner - changed title to Automatic expiration of related properties (objects or collections), i.e. when the FK attribute changes. you know, this thing.
-
repo owner - changed watchers to kb@retailarchitects.com
If A has a collection of 8000 B objects, does the modification of A.id go out and search for all 8000 Bs in the session and reset their "a" reference? that makes the assignment of A.id very expensive.
-
Account Deleted Replying to zzzeek:
If A has a collection of 8000 B objects, does the modification of A.id go out and search for all 8000 Bs in the session and reset their "a" reference? that makes the assignment of A.id very expensive. That's a good question. I admit, we aren't in the habit of changing primary keys very often so I haven't needed to address this. My simple version of this ticket for our project only expires related collections/objects that are connected when a foreign key changes. We nearly never change the primary key and the only case I can think of where we do, we are setting the relationship, not changing the foreign key. This will happen at the flush, right? But your point is the set shouldn't be so expensive.
It's this kind of thing dissuading you from setting foreign keys in the first place, isn't it?
-
repo owner I'd like to add a feature to relationship expire_on_local_attrs. You hit local attrs on the object and a local relationship expires, that's it, there's no interception of attributes on the related objects. The latter is a lot more complicated.
-
Account Deleted I think that is essentially what I've got, but I do not expire if it is along the save-update cascade since I expect those related objects to be "hand set", not just loaded from the database. So, at least for someone with a use case similar to ours, a feature for the relationship would work well.
-
repo owner how do you distinguish a save-update cascade event from others ?
-
Account Deleted I only expire ''relationships'' that aren't along the save-update cascade (actually, I use merge cascade, but save-update is probably more appropriate). So I check the property's cascade before expiring, essentially.
-
Account Deleted Please see http://groups.google.com/group/sqlalchemy/browse_thread/thread/53aa4ca4cd4e05cf for other implications.
-
repo owner recipe added, UsageRecipes/ExpireRelationshipOnFKChange
-
Account Deleted -
repo owner - changed milestone to 1.x.xx
-
repo owner - changed status to wontfix
this has been out there for six years, we have a recipe for someone who really wants to play with this, I don't see this as ever being committed to the ORM as it would create lots more complexity and support cases we can't take on.
- Log in to comment