Le mardi 30 septembre 2014 13:28:16 UTC+2, Simon King a écrit :
>
> On Tue, Sep 30, 2014 at 8:52 AM, tonthon <tont...@gmail.com <javascript:>> 
> wrote: 
> > Hi, 
> > 
> > I'm using dogpile cache to store objects in a redis database, here's the 
> > sample function I use for my tests : 
> > 
> >>>> @region.cache_on_arguments() 
> >>>> def get_my_model(id): 
> >>>>    return DBSession().query(Model).get(id) 
> > 
> > I retrieve models : 
> > 
> >>>> model1 = get_my_model(5) 
> >>>> model2 = get_my_model(5) 
> > 
> > model2 is retrieved from the cache. 
> > Since it's not attached to any session, when accessing a lazy-related 
> > object : 
> > 
> >>>> model2.owner 
> > 
> > I get a a DetachedInstanceError 
> > I found a turnaround : 
> > 
> >>>> DBSession().enable_relationship_loading(model2) 
> >>>> model2.owner 
> > 
> > that allows me to do what I want, but I'm not really satisfied with this 
> > design. 
> > 
> > Is it a clean way to go or should I review my caching strategy ? 
> > 
>
> The normal approach is to use session.merge() to attach a cached 
> object to a session. Note that session.merge() actually returns a *new 
> instance* attached to the session - it doesn't attach the instance 
> that you passed in: 
>
>   http://docs.sqlalchemy.org/en/latest/orm/session.html#merging 
>
> There's also a sophisticated example of using dogpile.cache at: 
>
>   http://docs.sqlalchemy.org/en/latest/orm/examples.html#examples-caching 
>
> Hope that helps, 
>
> Simon 
>


Hi,

I didn't knew merge was supposes to be used in such a case, it works like a 
charm.
Following that tip, I've added this decorator :

>>> def cache_wrapper(func):                   
>>>     """ ensure a model returned from a cached function is attached to 
the current session """                                     
>>>     def cached_func_wrapper(*args, 
**kwargs):                                   
>>>         obj = func(*args, 
**kwargs)                                             
>>>         if object_session(obj) is None and 
has_identity(obj):                   
>>>             obj = 
DBSESSION().merge(obj)                                        
>>>         return 
obj                                                              
>>>     return cached_func_wrapper  

So the cached function is like this one :
>>> @cache_wrapper
>>> @region.cache_on_arguments() 
>>> def get_my_model(id): 
>>>    return DBSession().query(Model).get(id) 

I'll have a look at the examples you pointed.

Thanks a lot for your answer, 
Regards,

Gaston
http://www.majerti.fr

-- 
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/d/optout.

Reply via email to