2016-11-21 3 views
1

У меня есть настройка веб-страницы пирамиды. Один из видов делает что-то вроде этого: -Запросы SQLAlchemy - когда они выполняются?

sql_list = do_a_query() 
handle_a_post_request(request) 
return dict(sql_list=sql_list) 

def do_a_query(): 
    request.db.query(WhatIAmLookingFor) 

The (мако, но я думаю, что это не имеет значения) шаблон затем обрабатывает отображение моего веб-страницы на основе данных в sql_list.

В функции handle_a_post_request я изменяю сеанс (и запускаю commit()) на основе запроса на отправку. Эти изменения появляются на результирующей странице, которая подсказывает мне, что сам запрос фактически «запускается» или выполняется, когда он вызывается в моем шаблоне. Поскольку я использую mako, вызов выполняется с использованием: -

% for row in sql_list: 
<tr> 
    <td> ${row[0]} </td> 
    <td> ${row[1]} </td> 
    <td> ${row[2]} </td> 
</tr> 

Является ли мое заключение правильным? Когда именно запрос sqlalchemy «актуализирован», так что изменения в сеансе после этого момента больше не отображаются в «результате» запроса? Или мое понимание в корне ошибочно?

Меня беспокоит, что в будущем изменение функции do_a_query() (например, итерация по ее результатам для некоторой предварительной обработки до отображения) изменит поведение моей веб-страницы. Разумеется, «правильный» ответ - это просто переместить handle_a_post_request() раньше, но я хотел бы получить полное представление о том, что происходит в первую очередь.

+0

Я думаю, что вы можете столкнуться с '' autoflush'', посмотрите на это: http://stackoverflow.com/questions/4201455/sqlalchemy-whats-the-difference-between-flush-and-commit –

+0

Нет, определенно нет такого набора. –

ответ

1

Запрос, как правило, выполняется, когда вы выполняете итерацию по экземпляру Query. Query.all() - удобный способ построения списка из итератора Query. (Запросы также выполняются автоматически, когда вы пытаетесь загрузить устаревшие атрибуты, но для этого ответа не будем игнорировать их.)

Важно отметить, что ни в коем случае изменения в сеансе невидимы. По умолчанию SQLAlchemy гарантирует, что сеанс будет очищен в соответствующие моменты времени, так что изменения в сеансе отразятся на следующем запросе.

В вашем случае вы должны вернуть результат от .all() в do_a_query() вместо того, чтобы возвращать запрос.

+0

Спасибо, так что все, что запускает итерацию через экземпляр 'Query', выполнит запрос? Что делать, если я повторяю его дважды (и что-то происходит между обеими итерациями)? –

+0

@ NgOon-Ee Затем он выполнит два запроса. Если вы что-то измените в сеансе (добавьте экземпляр, удалите экземпляр, обновите экземпляр), тогда по умолчанию SQLAlchemy внесет необходимые изменения перед выполнением второго запроса. Если * другая транзакция * что-то меняет, то в зависимости от уровня изоляции вы можете или не можете увидеть изменения. – univerio

+0

Спасибо. Поэтому моя ошибка заключается в том, что экземпляр «Query» на самом деле представляет собой набор результатов. Благодарим вас за быстрое, точное и точное объяснение. –

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