SQLAlchemy - выберите пример обновления
Я ищу полный пример использования select для обновления в SQLAlchemy, но не нашел один googling. Мне нужно заблокировать одну строку и обновить столбец, следующий код не работает (блоки навсегда):
s = table.select(table.c.user=="test",for_update=True)
# Do update or not depending on the row
u = table.update().where(table.c.user=="test")
u.execute(email="foo")
Мне нужна фиксация? Как мне это сделать? Насколько я знаю, вам нужно:
начать транзакцию
выберите... для обновления
Обновить
совершают
Ответы
Ответ 1
Поздний ответ, но, возможно, кто-то найдет его полезным.
Во-первых, вам не нужно совершать (по крайней мере, не промежуточные запросы, о которых я предполагаю, что вы спрашиваете). Второй запрос зависает бесконечно, потому что вы эффективно создаете два параллельных подключения к базе данных. Первый - это получение блокировки выбранных записей, затем вторая попытка изменения заблокированных записей. Поэтому он не может работать должным образом. (Кстати, в приведенном примере вы вообще не вызываете первый запрос, поэтому я предполагаю, что в ваших реальных тестах вы где-то делали что-то вроде s.execute()
). Итак, для точечной работы нужно больше походить:
s = conn.execute(table.select(table.c.user=="test", for_update=True))
u = conn.execute(table.update().where(table.c.user=="test), {"email": "foo"})
conn.commit()
Конечно, в таком простом случае нет причин делать какие-либо блокировки, но я думаю, что это только пример, и вы планировали добавить дополнительную логику между этими двумя вызовами.
Ответ 2
Если вы используете ORM, попробуйте with_for_update:
foo = session.query(Foo).filter(Foo.id==1234).with_for_update().one()
# this row is now locked
foo.name = 'bar'
session.add(foo)
session.commit()
# this row is now unlocked
Ответ 3
Да, вам необходимо выполнить фиксацию, которую вы можете выполнить на Engine
или создать a Transaction
явно. Также модификаторы указаны в методе values(...)
, а не execute
:
>>> conn.execute(users.update().
... where(table.c.user=="test").
... values(email="foo")
... )
>>> my_engine.commit()