I'd note that those subqueryloads() render the effectiveness of yield_per() to 
be almost nil.

This is how subqueryload works:


query(Parent).options(subqueryload(Parent.child)).all()

will give you:


"SELECT * FROM parent"

then, the moment a "parent" row is fetched, the first "child" collection is 
referenced to be loaded, then the query emitted is:

"SELECT * FROM child JOIN (SELECT * FROM parent) AS a on a.id=child.id_a"

that is, the second query loads all child rows for all parents in the entire 
result.   

So let's say we do yield_per(), so that SQLAlchemy only processes the first 100 
rows before handing them out.   As soon as you hit either of those two 
subqueryloaded collections, the yield_per() is mostly thrown out the window - 
they will each load the entire list of child objects for the whole result, 
which right there will grow memory to be as big as your entire result.

The next thing I'd look at is that second query for ModelC.   You can also load 
those upfront so that you don't need to do a query each time:

modelcs = dict(
    sess.query(ModelC.id_a, 
ModelC).join(ModelC.a).filter(ModelA.parent_id=<same integer you're using 
against ModelA>)
)

then you have a dictionary of "id_a->ModelC" as you loop through your ModelA 
records.   All the ModelC's are already in the session, so you don't need to 
use merge(), which is also not a super quick operation.  If an "id_a" is not in 
the dictionary then you know to create a new ModelC and use Session.add() to 
put it in.   If you're limiting the ModelA rows using a LIMIT or window recipe 
like I mentioned earlier, you'd apply that same criteria to the loading of the 
"modelcs".

Later on you're doing something with query(ModelC).first() in a loop which is 
also something I hope isn't in the real application - looking there is seems 
like you'd only need to say query(ModelC).delete().

Watching the SQL emitted with echo=True, and in some cases also seeing how 
large the results coming in are using echo='debug', is something I strongly 
recommend when first profiling an application.





On Feb 23, 2012, at 8:18 AM, Vlad K. wrote:

> 
> And yet again the problem is not in SQLAlchemy but in Pyramid.... Sorry, from 
> now on, I'll first try writing test scripts without Pyramid to see where the 
> problem is, I just don't have time for that kind of debugging so I'm wasting 
> yours. :)
> 
> 
> Thanks. I'll write to Pylons Discuss list, but the test script is here 
> nevertheless. Comment out line 266 (and remove imports) to disable Pyramid 
> and see it work okay. Without Pyramid (but even with Transaction and 
> ZopeTransactionExtension), the gcdelta is 0 or negative per batch of 200 
> iterations. With Pyramid bootstrapped, gcdelta is in thousands per batch of 
> 200 iterations.
> 
> https://gist.github.com/d669e958c54869c69831
> 
> 
> .oO V Oo.
> 
> 
> On 02/23/2012 02:41 AM, Michael Bayer wrote:
>> On Feb 22, 2012, at 6:36 PM, Vlad K. wrote:
>> 
>>> Okay, thanks to this article:
>>> 
>>> http://neverfear.org/blog/view/155/Investigating_memory_leaks_in_Python
>>> 
>>> 
>>> I made similar plot of object counts in time, showing top 50 types. The 
>>> resulting PDF is here (you might wish to download it first, Google messes 
>>> it up for me):
>>> 
>>> https://docs.google.com/open?id=0ByLiBlA59qDwYTY1MGIzYWEtYjMxZi00ZDVlLTk0OTEtOGI2ZjA3NDgyM2Y3
>>> 
>>> 
>>> Everything seems to linearly grow in count. Something is keeping all those 
>>> objects reference somewhere. What could possibly be the cause?
>> 
>> can you provide a self-contained, single file test case that illustrates the 
>> memory growth ?
>> 
>> 
> 
> -- 
> 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