2012-03-21 1 views
4

В данный момент я запрашиваю моя база данных так:Возможно ли генераторное запрос базы данных по sqlalchemy?

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 верно.

ответ

0

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

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

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

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

2

Объекты запроса могут рассматриваться как итераторы как есть. 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

Если я не совершаю, все будет потеряно, если мой скрипт выйдет из строя ... Поэтому было бы лучше обернуть фактический скрипт циклом while, который будет продолжать итерацию, если есть авторы с 'queried == 0 «правда, правильно? – Aufwind

+0

Естественное место для совершения происходит только после того, как ваша петля завершена. Но если у вас много изменений, это может быть большая транзакция и не работает хорошо. Если это так, срез в исходной постановке проблемы может быть лучше. Это зависит от того, что вы делаете и сколько строк, вероятно, будет возвращено. – wberry

+0

В качестве обновления postgres поддерживает функцию прослушивания/уведомления api – morissette

Смежные вопросы