Re: [sqlalchemy] Query caching allows two objects representing same underlying data in session?

2013-07-16 Thread Claudio Freire
On Mon, Jul 15, 2013 at 8:02 PM, Michael Bayer mike...@zzzcomputing.com wrote:
 On Jul 15, 2013, at 4:51 PM, Amir Elaguizy aelag...@gmail.com wrote:

 I'm having this weird problem using the query caching recipes in which two 
 instances of a model representing the same underlying dataset will both get 
 into the session.

 I know this is happening because I put all of the models in a set() and 
 there are two instances with the same underlying database row id.

 I was under the impression that the session itself would handle the case 
 that an object coming from the query cache is already in the session, 
 preventing duplication. Is this not the case?

 well you need to be using the merge() aspect of it, which will reconcile an 
 existing identity that's already in the session.  the recipe as written uses 
 merge_result() so will ensure this, yes.This only deals with the identity 
 map though, if you have an object pending with a given identity, its not in 
 the identity map.   I'd advise against heavy usage of cached queries 
 overlapping with lots of pending objects within the same sets because things 
 can get very crazy.

Because of all that crazyness, that I came to the realization that you
can only cache detached instances, and you can never merge them into
your session. If you do, you may end up with a concurrency mess, if
two threads want to merge the same cached instance into a session.

To put a cached instance into a session, you must first copy it, then
update. How to do that, is very application-specific, and I don't
think it can be automated.

-- 
You received this message because you are subscribed to the Google Groups 
sqlalchemy group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to sqlalchemy+unsubscr...@googlegroups.com.
To post to this group, send email to sqlalchemy@googlegroups.com.
Visit this group at http://groups.google.com/group/sqlalchemy.
For more options, visit https://groups.google.com/groups/opt_out.




Re: [sqlalchemy] Query caching allows two objects representing same underlying data in session?

2013-07-16 Thread Michael Bayer

On Jul 16, 2013, at 1:47 PM, Claudio Freire klaussfre...@gmail.com wrote:

 On Mon, Jul 15, 2013 at 8:02 PM, Michael Bayer mike...@zzzcomputing.com 
 wrote:
 On Jul 15, 2013, at 4:51 PM, Amir Elaguizy aelag...@gmail.com wrote:
 
 I'm having this weird problem using the query caching recipes in which two 
 instances of a model representing the same underlying dataset will both get 
 into the session.
 
 I know this is happening because I put all of the models in a set() and 
 there are two instances with the same underlying database row id.
 
 I was under the impression that the session itself would handle the case 
 that an object coming from the query cache is already in the session, 
 preventing duplication. Is this not the case?
 
 well you need to be using the merge() aspect of it, which will reconcile an 
 existing identity that's already in the session.  the recipe as written uses 
 merge_result() so will ensure this, yes.This only deals with the 
 identity map though, if you have an object pending with a given identity, 
 its not in the identity map.   I'd advise against heavy usage of cached 
 queries overlapping with lots of pending objects within the same sets 
 because things can get very crazy.
 
 Because of all that crazyness, that I came to the realization that you
 can only cache detached instances, and you can never merge them into
 your session. If you do, you may end up with a concurrency mess, if
 two threads want to merge the same cached instance into a session.

a merge() creates a copy of the object.  So the model is, the object that is 
actually *in* the cache remains detached.  but you always create an attached 
copy of it to work with locally.  That object can then fire off loaders for 
additional collections and relationships and such, and if you use the caching 
recipe fully, those relationships themselves can be cached.  It's much more 
efficient to store a cached version of an A associated via many to one to a B 
which is many to one to a C as the A, B, C separately, rather than as a graph - 
otherwise all the A's B's are recaching redundant B's C's, taking up lots more 
space in the cache and over the network.


 
 To put a cached instance into a session, you must first copy it, then
 update. How to do that, is very application-specific, and I don't
 think it can be automated.

that's what merge(don't_load=True) does. If your object has other aspects 
to it that are outside of what's mapped, then there are event hooks you can use 
to re-instantiate additional state.




-- 
You received this message because you are subscribed to the Google Groups 
sqlalchemy group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to sqlalchemy+unsubscr...@googlegroups.com.
To post to this group, send email to sqlalchemy@googlegroups.com.
Visit this group at http://groups.google.com/group/sqlalchemy.
For more options, visit https://groups.google.com/groups/opt_out.




Re: [sqlalchemy] Query caching allows two objects representing same underlying data in session?

2013-07-16 Thread Claudio Freire
On Tue, Jul 16, 2013 at 4:22 PM, Michael Bayer mike...@zzzcomputing.com wrote:
 To put a cached instance into a session, you must first copy it, then
 update. How to do that, is very application-specific, and I don't
 think it can be automated.

 that's what merge(don't_load=True) does. If your object has other aspects 
 to it that are outside of what's mapped, then there are event hooks you can 
 use to re-instantiate additional state.


Oh... didn't know that. That's interesting. I've never toyed with the
event system before, but I guess there's an incentive right there.

-- 
You received this message because you are subscribed to the Google Groups 
sqlalchemy group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to sqlalchemy+unsubscr...@googlegroups.com.
To post to this group, send email to sqlalchemy@googlegroups.com.
Visit this group at http://groups.google.com/group/sqlalchemy.
For more options, visit https://groups.google.com/groups/opt_out.




[sqlalchemy] unregister mapper event

2013-07-16 Thread Greg Yang
Is it possible to remove mapper events? Specifically I want to call 
event.remove(mapper, 'mapper_configured', fn) but I get an error back 
saying Mapper is not iterable.

-- 
You received this message because you are subscribed to the Google Groups 
sqlalchemy group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to sqlalchemy+unsubscr...@googlegroups.com.
To post to this group, send email to sqlalchemy@googlegroups.com.
Visit this group at http://groups.google.com/group/sqlalchemy.
For more options, visit https://groups.google.com/groups/opt_out.




Re: [sqlalchemy] unregister mapper event

2013-07-16 Thread Michael Bayer
It's an unimplemented TODO right now.There are ways to remove the events 
through non-public means, but for it to be done correctly in all cases, there 
are lots of twists and turns that need to be managed (such as, unregistering an 
event on an abstract base, an event that has propagate=True, etc).For the 
full feature add, I will probably have to find some way to have an event 
function keep track of every listener collection it becomes a part of, so that 
it can be removed from all of them in a simple way.

I'd advise first trying not to rely upon needing to remove events, after that 
I'd say create your own mutable collection of listeners for those cases where 
you really need to add/remove them:

listeners = set()

@event.listens_for(MyClass, my_event)
def dispatch(cls, mapper):
   for fn in listeners:
fn(cls, mapper)

you can add/remove functions from listeners above.


 

On Jul 16, 2013, at 7:24 PM, Greg Yang sorcerero...@gmail.com wrote:

 Is it possible to remove mapper events? Specifically I want to call 
 event.remove(mapper, 'mapper_configured', fn) but I get an error back saying 
 Mapper is not iterable.
 
 -- 
 You received this message because you are subscribed to the Google Groups 
 sqlalchemy group.
 To unsubscribe from this group and stop receiving emails from it, send an 
 email to sqlalchemy+unsubscr...@googlegroups.com.
 To post to this group, send email to sqlalchemy@googlegroups.com.
 Visit this group at http://groups.google.com/group/sqlalchemy.
 For more options, visit https://groups.google.com/groups/opt_out.
  
  

-- 
You received this message because you are subscribed to the Google Groups 
sqlalchemy group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to sqlalchemy+unsubscr...@googlegroups.com.
To post to this group, send email to sqlalchemy@googlegroups.com.
Visit this group at http://groups.google.com/group/sqlalchemy.
For more options, visit https://groups.google.com/groups/opt_out.