Our web app needs to use an "immutable" database object structure,
i.e.some mapped classes resp.tables will change with administrative
runs only. These objects mostly are referenced by other (mutable)
persistant objects.
The structure fits well into memory and can remain in each process for
its lifetime.

Loading these objects with any new or clear()ed session would
drastically impact performance. Even more important, these immutable
objects should be easily useable as dict keys, requiring them to
reliable keep their identity. (These objects are nice candidates for
memcached but this is not about instance identity.)

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.
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.
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(). Required would be the event
semantics "always called when instance got sync'ed with the DB".


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

Regards,
 Ruben

SA Version: 0.4.x
Related Links:
a recipe for unique objects, but about instance creation, not about
instance loading:
http://www.sqlalchemy.org/trac/wiki/UsageRecipes/UniqueObject
query caching thread but about performance with complex joins:
http://groups.google.de/group/sqlalchemy/browse_thread/thread/e7294628673aad12/6b65276bcd9e8e5a?lnk=gst&q=create_instance#

--~--~---------~--~----~------------~-------~--~----~
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