Hello.

Thank you for the tips. I stick to my simple approach for the time being:

    _rows = q.all()
    rows = unwrap(_rows)

I need the cache within the context of one method only.

Ladislav Lenart


Od: "Michael Bayer" <mike...@zzzcomputing.com>
> On Sep 27, 2012, at 4:37 PM, Ladislav Lenart wrote:
> 
> > Hello.
> > 
> > Thank you for the explanation. I was relatively close :-)
> > 
> > I understand the rationale but don't like the impact it has:
> > If I query the database for something, I expect it to be available via slot
> > access afterwards, but unless I hold onto the results, it won't be.
> > 
> > I guess this is one of those tricky bits one has to be caution about :-)
> 
> typically when I really want things to be "cached", I do this:
> 
> cache = dict((obj.id, obj) for obj in session.query(Class))
> 
> with those strong references set up, I control the scope of objects as though 
> the Session weren't really involved.
> 
> The Session has an option for a "strong referencing" identity map, which is a 
> holdover from the old days when the whole "weak" idea wasn't available yet.   
> I've tried to deprecate this approach though there are some users still using 
> it.    It should be in the docs if you look for it.
> 
> 
> 
> > 
> > Ladislav Lenart
> > 
> > 
> > On 27.9.2012 22:20, Michael Bayer wrote:
> >> 
> >> On Sep 27, 2012, at 3:17 PM, Ladislav Lenart wrote:
> >> 
> >>> Update.
> >>> 
> >>> Te unwrap version works only if the original result of q.all() is kept 
> >>> around:
> >>> 
> >>>   def test_access(self):
> >>>       q = self.session.query(Foo, Bar).with_labels()
> >>>       q = q.filter(Foo.bar_id == Bar.id)
> >>>       # Only this combination works:
> >>>       _rows = q.all()
> >>>       rows = unwrap(_rows)
> >>>       assert len(rows) > 0
> >>>       with self.assert_no_sql_while():
> >>>           for each in rows:
> >>>               each.bar.data
> >>> 
> >>> I have also rewritten unwrap to:
> >>> 
> >>>   def unwrap(items):
> >>>       def f(each):
> >>>           if isinstance(each, tuple) and len(each) > 0:
> >>>               return each[0]
> >>>           else:
> >>>               return each
> >>>       return map(f, items)
> >>> 
> >>> because it is now completely useless as a generator.
> >>> 
> >>> I am completely lost now. Does this have to do something with weak 
> >>> references
> >>> and too eager garbage collection? I would expect that if a query fetches 
> >>> some
> >>> objects, session will keep them all until explicitly removed from it to
> >>> eliminate successive SQL queries.
> >> 
> >> the Session does not strongly reference items that have no pending changes 
> >> on them.    This allows code such as this:
> >> 
> >> for criterion in crit:
> >>    objects = session.query(Cls).filter(criterion).all()
> >>   _process_objects(objects)
> >> 
> >> above, if the Session strongly referenced all objects until explicitly 
> >> removed, logic like the above would cause memory to grow unbounded.   
> >> 
> >> Of course, if the objects were referred to by other objects, such as 
> >> members of a collection or inter-object reference, they get a strong 
> >> reference via that collection, but in your example there is no linkage 
> >> between "Foo" and "Bar" until you actually invoke the path between two 
> >> particular instances.
> >> 
> >> cPython uses referencing counting for garbage collection, so assuming an 
> >> object has no reference cycles, it is garbage collected immediately as 
> >> soon as its strong reference count goes to zero.
> > 
> > -- 
> > 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.
> > 
> 
> -- 
> 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.
> 
> 

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

Reply via email to