On Jun 2, 2008, at 3:07 AM, Nebur wrote:

>
> Loading these objects with any new or clear()ed session would
> drastically impact performance.

im assuming the performance increase is due to the reduced overhead in  
creating objects  ?  From what I can see, you are still issuing SQL,  
still processing result rows, still populating state in the given  
instances....all of which is very time consuming.   Plus, your scheme  
actually wont even save object creation overhead since you can't  
exactly do it that way...

>
> I'm currently using this recipe:
> Provide a MapperExtension with create_instance and maintain a custom
> cache for the immutable objects (additionally to the short-living
> identity maps of the sessions).
>
> class UniqueByPrikeyMapper(MapperExtension):
>    def create_instance(self, mapper, selectcontext, row, class_):
>        key = row[class_.c.id] # there's a primary key "id"  always
>        try:
>            return get_instance_from_somewhere(class_, key=key)
>        except KeyError: # instance not in the cache: put it there
>            res = class_.__new__(class_)
>            register_instance_somewhere(class_,
> key=row[instance.c.id])
>            return res
>
> Now, any persistant instance gets cached fine when loaded. But freshly
> created objects need a separate treatment.

this wont work out of the box because a particular object instance can  
only be in one Session at a time.   For this kind of use case we  
provide a method called "merge()" which takes a dont_load=True  
argument to create local copies of objects in sessions.

>
> Since we use the auto generated "id" as key, any new instance needs to
> be "manually" put into the cache after is was flush()ed. I've fiddled
> with a SessionExtension/after_flush(), where the new instances can be
> found in flush_context.uow.new. This could be a place to put new
> instances into the cache althought is seems somewhat hackish.

why not session.new ?  "context.uow.new" is gone in 0.5.

> Alternatively, we can re-load any instance after flush() to let
> create_instance() run, and throw away the original reference.
> An attempt to use populate_instance() for caching instances there (and
> only there) failed. populate_instance() is *not* run when the auto-
> generated id is populated after flush().

after_flush() is a decent place to do things like this (or even  
after_insert()).  populate_instance() corresponds to object state  
loaded from the database but it would be wasteful and complex to rely  
upon an expunge-reload scheme just for state management.

> Required would be the event
> semantics "always called when instance got sync'ed with the DB".

that is the populate_instance() method on the load side.  On the save  
side it's after_insert()/after_update().

> Someone has a better practice / comments / can see shortcomings ?

what is the specific overhead you are looking to reduce ?  I don't yet  
see much savings here (well, I don't see any, but its only 10:30 AM  
for me).  An ORM-external approach could reduce SQL and result  
processing overhead a lot more vastly.



--~--~---------~--~----~------------~-------~--~----~
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 [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/sqlalchemy?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to