Возможен ли генераторный запрос к базе данных с помощью sqlalchemy? - PullRequest
5 голосов
/ 21 марта 2012

В данный момент я запрашиваю свою базу данных следующим образом:

for author in session.query(Author).filter(Author.queried==0).slice(0, 1000):
    print "Processing:", author
    # do stuff and commit later on

Это означает, что каждые 1000 авторов должны перезапускать скрипт.

Возможно ли сделать скрипт бесконечным (или пока есть авторы)?Под этим я подразумеваю, что если можно превратить

session.query(Author).filter(Author.queried==0).slice(0, 1000)

в некий генератор, который выдаст следующего автора, для которого queried==0 истинно .

Ответы [ 2 ]

2 голосов
/ 22 марта 2012

Объекты запросов могут рассматриваться как итераторы как есть. SQL будет выполнен, как только вы начнете использовать данные из итератора запроса. Пример:

for author in session.query(Author).filter(Author.queried==0):
    print "Processing: ", author

Ваш вопрос использует слово «бесконечно», поэтому слово предостережение. SQL не является API обработки событий; Вы не можете просто выполнить запрос, который выполняется «навсегда» и выплевывает каждую новую строку, когда она добавляется в таблицу. Хотелось бы, чтобы это было возможно, но это не так.

Если вы намерены обнаруживать новые строки, вам придется регулярно опрашивать один и тот же запрос и создавать индикатор в вашей модели данных, который позволит вам указать, какие строки новые. Вы, кажется, представляете это сейчас с queried столбцом. В этом случае в цикле for выше вы можете установить author.queried = 1 и session.add(author). Но вы не можете session.commit() внутри цикла.

0 голосов
/ 21 марта 2012

Поскольку запрос превращен в эквивалентный оператор SQL SELECT, вы сможете получить только набор строк Author, для которых запрашивается значение 0, существовавшее при запуске этой транзакции. Любые обновления в столбце запроса автора не изменят текущий набор SELECT.

Если вы хотите продолжить обработку всех строк Author, даже если их больше 1000, вы можете сделать

for author in session.query(Author).filter(Author.queried==0):
    print "Processing:", author

Метод __iter__ объекта Query будет вызван автоматически, и тот же итератор будет возвращен как вызов instances для объекта Query.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...