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 :-) 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 [email protected]. 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.
