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.

Reply via email to