Подтвердить что ты не робот

Sqlalchemy - Разница между запросом и query.all для циклов

Я хотел бы спросить, в чем разница между

for row in session.Query(Model1):
    pass

и

for row in session.Query(Model1).all():
    pass

является первым, каким-то образом, итератором, бомбардирующим вашу БД единичными запросами, и последние "нетерпеливые" задают все это как список (например, range (x) vs xrange (x))?

4b9b3361

Ответ 1

Нет, нет разницы в трафике БД. Разница лишь в том, что for row in session.Query(Model1) ORM работает с каждой строкой, когда он собирается передать ее вам, в то время как for row in session.Query(Model1).all() работает с ORM. все строки, прежде чем начать давать их вам.

Обратите внимание, что q.all() является просто сахаром для list(q), т.е. собирает все, что q.all() генератором, в список. Вот исходный код для него в классе Query (найдите def all в связанном источнике):

def all(self):
    """Return the results represented by this ''Query'' as a list.

    This results in an execution of the underlying query.

    """
    return list(self)

... где self, объект запроса, является итеративным, то есть имеет метод __iter__.

Таким образом, логически оба пути абсолютно одинаковы с точки зрения трафика БД; оба заканчивают тем, что вызывают query.__iter__() чтобы получить итератор строки, и next() проходят через него.

Практическое отличие состоит в том, что первый может начать давать вам строки, как только их данные поступят, "потоковая" результирующая база данных для вас, с меньшим использованием памяти и задержкой. Я не могу с уверенностью утверждать, что все текущие реализации движка делают это (я надеюсь, что они делают!). В любом случае последняя версия препятствует такой эффективности, без веской причины.