Hello.

> assuming cls.foo is a many-to-one, it will produce the correct result,
> but will be far worse in terms of memory and performance, as the
> subqueryload() call will be invoked for each distinct batch of 50 rows,
> across the *full* result set.  So if your result has 1000 rows, and the
> number of "bars" total is 10000, you will load 10000 additional rows for
> *each* yield per of 50.

Ok, I think I get it. Is there a way to make it all work without the performance
penalty of subqueryload? For example, what will happen if I replace it with
joinedload(cls.bars)?

Ladislav Lenart


On 4.6.2013 16:19, Michael Bayer wrote:
> 
> On Jun 4, 2013, at 8:18 AM, Ladislav Lenart <lenart...@volny.cz> wrote:
> 
>> Hello.
>>
>> I have a hard time to understand the following comment for Query.yield_per():
> 
>>      Yield only ``count`` rows at a time.
>>
>>        WARNING: use this method with caution; if the same instance is present
>>        in more than one batch of rows, end-user changes to attributes will be
>>        overwritten.
>>
>>        In particular, it's usually impossible to use this setting with
>>        eagerly loaded collections (i.e. any lazy='joined' or 'subquery')
>>        since those collections will be cleared for a new load when
>>        encountered in a subsequent result batch.   In the case of 'subquery'
>>        loading, the full result for all rows is fetched which generally
>>        defeats the purpose of :meth:`~sqlalchemy.orm.query.Query.yield_per`.
>>
>>        Also note that many DBAPIs do not "stream" results, pre-buffering
>>        all rows before making them available, including mysql-python and
>>        psycopg2.  :meth:`~sqlalchemy.orm.query.Query.yield_per` will also
>>        set the ``stream_results`` execution
>>        option to ``True``, which currently is only understood by psycopg2
>>        and causes server side cursors to be used.
>>
>> Suppose I have a code like this:
>>
>>    q = session.query(cls).filter(...)
>>    q = q.options(
>>        joinedload(cls.foo),
>>      subqueryload(cls.bars),
>>    )
>>    for each in q.yield_per(50):
>>        # access each.foo or each.bars
>>
>> Does it work? Is so, why? If not, why?
> 
> assuming cls.foo is a many-to-one, it will produce the correct result, but 
> will be far worse in terms of memory and performance, as the subqueryload() 
> call will be invoked for each distinct batch of 50 rows, across the *full* 
> result set.  So if your result has 1000 rows, and the number of "bars" total 
> is 10000, you will load 10000 additional rows for *each* yield per of 50.
> 


-- 
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?hl=en.
For more options, visit https://groups.google.com/groups/opt_out.


Reply via email to