Sqlalchemy – разница между запросом и query.all в циклах for

StackOverflow https://stackoverflow.com/questions/1078383

  •  21-08-2019
  •  | 
  •  

Вопрос

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

for row in session.Query(Model1):
    pass

и

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

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

Это было полезно?

Решение

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

Обратите внимание, что q.all() это просто сахар для list(q), т.е.собираем все, что выдает генератор, в список.Здесь исходный код для этого в 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()пробираясь через это.

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top