Лучше понять проблемы SQLalchemy `yield_per ()`

ЦитироватьSQLalchemy документация:

Метод Query.yield_per () несовместим с большинством схем загрузки, включая подзапрос и объединенную загрузку с коллекциями.

Предупреждение

Используйте этот метод с осторожностью; если один и тот же экземпляр присутствует в нескольких пакетах строк, изменения конечного пользователя в атрибутах будут перезаписаны.

В частности, этот параметр обычно невозможно использовать с активно загруженными коллекциями (т. Е. С любым отложенным = 'присоединенным' или 'подзапросом'), поскольку эти коллекции будут очищены для новой загрузки при обнаружении в последующем пакете результатов. В случае загрузки «подзапроса» извлекается полный результат для всех строк, что в целом не соответствует назначению yield_per ().

Также обратите внимание, что хотя yield_per () установит для параметра выполнения stream_results значение True, в настоящее время это понимается только на диалекте psycopg2, который будет транслировать результаты с использованием серверных курсоров вместо предварительной буферизации всех строк для этого запроса. Другие DBAPI предварительно буферизуют все строки перед тем, как сделать их доступными. Использование в памяти необработанных строк базы данных намного меньше, чем в ORM-отображаемом объекте, но все же должно учитываться при сравнительном анализе.

У меня действительно есть проблема с пониманием того, какyield_per() работает и в чем именно заключается проблема при использовании этого метода. Также, как правильно обойти эти проблемы и продолжать использовать эту функцию для перебора огромного количества строк.

Мне интересна вся ваша конструктивная информация, но вот несколько подсказок:

Как может быть несколько экземпляров одной строки? Только через отношения (если две строки таблицы итерации имеют FK для одной строки в другой таблице)? Есть ли проблема, если вы не знаете, что это происходит, или вы только читаете атрибуты в отношениях?Ленивый = 'присоединенный' или 'подзапрос' невозможен, но почему именно? Они оба являются просто частями вашего запроса, по которому вы звонитеyield_per().Если они очищены в последующем пакете результатов, просто загрузите его снова. Так в чем же проблема? Или единственная проблема, которую вы теряете изменения ваших отношений, если внес изменения?Почему в случае загрузки «подзапроса» выбираются все строки? SQL Server может потребоваться сохранить большую таблицу, но тогда почему бы просто не возвращать результат в виде пакетов один за другим для всего запроса?В примере вyield_per() доктор q = sess.query(Object).yield_per(100).options(lazyload('*'), joinedload(Object.some_related)) они деактивируютlazyload('*') но держите единый объединенный груз. Есть ли способ еще использоватьyield_per() с нетерпением? Какие условия?Они говорятpsycopg2 это единственный DBAPI, который поддерживает результаты потока. Так что это единственный DBAPI, который вы можете использовать сyield_per()? Насколько я понимаюyield_per используетcursor.fetchmany() (пример) функция DBAPI, которая поддерживает многие из них. И насколько я понимаюcursor.fetchmany() поддерживает выборку только части результата и не получает все (если он будет выбирать все, почему функция существует?)У меня такое ощущение, чтоyield_per() полностью безопасен (даже с eagerload), если вы только делаете доступ для чтения (например, для статистики). Это верно?

Ответы на вопрос(1)

Ваш ответ на вопрос