Подтвердить что ты не робот

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") 

Мне нужна фиксация? Как мне это сделать? Насколько я знаю, вам нужно: начать транзакцию выберите... для обновления Обновить совершают

4b9b3361

Ответ 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()