On Sep 27, 2012, at 1:28 AM, Michael Kowalchik wrote: > Lets say I have object A that's in the cache and it has a relationship, A.B > that was stored along with it in the cache. If I retrieve A from the cache I > can get A.B and I get the cached copy of B. If B is modified, however, then > my simple cache invalidator event handler doesn't see that B is cached (no > __cached__ property on B) and B gets committed to the database without the > cached copy of A being invalidated. Now subsequent cache hits of A will have > a stale A.B relationship.
> So my question is, is there a clean / simple way to mark A for invalidation > when B is modified? I've come up with a few schemes but all of them seem > brittle, complicated, and my intuition is telling me that I'm reinventing the > wheel; that some facility in SQLAlchemy itself may be useful in walking this > relationship graph to find loaded, connected relationships who's cached > represenations might need to be invalidated. Alternatively, is there another > pattern that would be better suited to this kind of object-level caching? well you're checking __cached__ in an after_commit() hook. usually the technique here if you want relationships is to *cascade* the operation at that point. So assuming its OK that you'd be leading from A, when A is __cached__, checking it for "dirty" also means you need to traverse down its relationships. this is a straight ahead graph traversal problem, but you're right SQLA obviously has this function built into it. you can use the cascade_iterator() feature of mapper(): state = instance_state(myobject) mapper = state.mapper for related in mapper.cascade_iterator("save-update", state): # do check where above you're cascading along the "save-update" cascade setting which is enabled on all relationships by default. The other pattern might be, to drive from how you phrased it, "mark A for invalidation when B is modified". That is, use event handlers so that when a B is attached to an A, it gets associated in some way such that a change on B propagates up to the A (which would mean more event handlers .... we dont as yet have an event "any change on class X", they are all per-attribute. this is more involved but could save you from lots of traversals in your after_commit hook depending on the circumstances. -- You received this message because you are subscribed to the Google Groups "sqlalchemy" group. To post to this group, send email to sqlalchemy@googlegroups.com. To unsubscribe from this group, send email to sqlalchemy+unsubscr...@googlegroups.com. For more options, visit this group at http://groups.google.com/group/sqlalchemy?hl=en.