Большинство реализаций DBAPI полностью буферизуют строки по мере их выборки - поэтому обычно, прежде чем SQLAlchemy ORM даже получит один результат, весь набор результатов находится в памяти.
Но тогда способ работы Queryявляется то, что он полностью загружает данный набор результатов по умолчанию, прежде чем вернуть вам ваши объекты.Обоснование здесь относится к запросам, которые относятся не только к простым инструкциям SELECT, но и к другим таблицам, которые могут возвращать одну и ту же идентичность объекта несколько раз в одном наборе результатов (что обычно при активной загрузке), полный набор строк должен находиться в памяти, поэтомучто правильные результаты могут быть возвращены - в противном случае коллекции и тому подобное могут быть заполнены только частично.
Таким образом, Query предлагает возможность изменить это поведение, то есть вызов yield_per () http://www.sqlalchemy.org/docs/orm/query.html?highlight=yield_per#sqlalchemy.orm.query.Query.yield_per.Этот вызов приведет к тому, что запрос выдаст строки в пакетах, где вы задаете размер пакета.Как указано в документации, это уместно только в том случае, если вы не выполняете какую-либо активную загрузку коллекций - так что это в основном, если вы действительно знаете, что делаете.А также, если базовые строки DBAPI предварительно буферизуют строки, это все равно приведет к дополнительным затратам памяти, поэтому подход масштабируется только немного лучше, чем без него.
Я почти никогда не использую yield_per () - вместо этого я используюлучшую версию подхода LIMIT, которую вы предлагаете выше, используя оконные функции.У LIMIT и OFFSET огромная проблема: очень большие значения OFFSET приводят к тому, что запрос становится все медленнее и медленнее, так как OFFSET из N заставляет его перелистывать N строк - это все равно, что выполнять один и тот же запрос пятьдесят раз вместо одного, каждый раз читаявсе большее и большее количество рядов.При подходе оконной функции я предварительно выбираю набор значений «окна», которые относятся к фрагментам таблицы, которую я хочу выбрать.Затем я генерирую отдельные операторы SELECT, которые каждый раз извлекают из одного из этих окон.
Подход к оконной функции есть в вики на http://www.sqlalchemy.org/trac/wiki/UsageRecipes/WindowedRangeQuery, и я использую его с большим успехом.
Также обратите внимание, что не все базы данных поддерживают оконные функции - вам нужны PG, Oracle или SQL Server.ИМХО использование хотя бы Postgresql определенно того стоит - если вы используете реляционную базу данных, вы можете использовать и лучшее.