ORM SQLAlchemy предназначен для использования вместе со слоем SQL, а не скрывать его. Но вы должны помнить об одной или двух вещах, когда используете ORM и обычный SQL в одной транзакции. По сути, с одной стороны, изменения данных ORM будут попадать в базу данных только тогда, когда вы сбрасываете изменения из своего сеанса. С другой стороны, операторы манипулирования данными SQL не влияют на объекты в вашем сеансе.
Так что, если вы скажете
for c in session.query(Stuff).all():
c.foo = c.foo+1
session.commit()
он будет делать то, что говорит, будет извлекать все объекты из базы данных, изменять все объекты, а затем, когда придет время сбрасывать изменения в базе данных, обновлять строки одну за другой.
Вместо этого вы должны сделать это:
session.execute(update(stuff_table, values={stuff_table.c.foo: stuff_table.c.foo + 1}))
session.commit()
Это будет выполняться как один запрос, как и следовало ожидать, и, поскольку по крайней мере конфигурация сеанса по умолчанию истекает все данные в сеансе при фиксации, у вас нет проблем с устаревшими данными.
В почти выпущенной серии 0.5 вы также можете использовать этот метод для обновления:
session.query(Stuff).update({Stuff.foo: Stuff.foo + 1})
session.commit()
Это будет в основном выполнять тот же оператор SQL, что и предыдущий фрагмент, но также будет выбирать измененные строки и истекать все устаревшие данные в сеансе. Если вы знаете, что вы не используете данные сеанса после обновления, вы также можете добавить synchronize_session = False в оператор обновления и избавиться от этого выбора.