2012-04-09 6 views
13

SQLAlchemy에서 select for update를 사용하는 예를 찾고 있지만 Google 검색 중 하나를 찾지 못했습니다. 단일 행을 잠그고 열을 업데이트해야하는 경우 다음 코드가 작동하지 않습니다 (영원히 차단됨) :SQLAlchemy - 업데이트 예제로 선택

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

하는 것도 쿼리 개체를 지적 원하는 것은 이것에 대한 새로운 방법이 있습니다 http://docs.sqlalchemy.org/en/rel_0_9 /orm/query.html#sqlalchemy.orm.query.Query.with_for_update –

답변

2

예, 당신이 Engine에서 실행 또는 명시 적으로 Transaction을 만들 수있는, 커밋해야합니까 커밋 업데이 트를 선택 트랜잭션을 시작합니다. 또한 수정은 values(...) 방법으로 지정하지 execute됩니다

>>> conn.execute(users.update(). 
...    where(table.c.user=="test"). 
...    values(email="foo") 
...    ) 
>>> my_engine.commit() 
+2

이 대답은 주어진 질문의 주요 지점 인 'SELECT ... FOR UPDATE'사용 예제를 놓치고 있습니다. 코드는 제안 된 형식으로 축소 될 수 있지만 더 이상 요청 된 구문을 사용하지 않습니다. 물론 @Mark가 레코드를 얻거나 록을 획득하는 것 사이에 추가 로직을 추가하지 않을 것이라면 그렇게 할 수 있습니다. – RobertT

6

늦은 대답,하지만 어쩌면 누군가는 유용하게 찾을 수 있습니다.

먼저 커밋 할 필요가 없습니다 (적어도 사이에 중개하지 않는 쿼리, 당신이 묻고 있다고 가정합니다). 데이터베이스에 대한 두 개의 동시 연결을 효과적으로 생성하기 때문에 두 번째 쿼리가 무기한 중지됩니다. 첫 번째는 선택한 레코드에 대한 잠금을 얻고 두 번째 레코드는 잠긴 레코드를 수정하려고 시도합니다. 그래서 제대로 작동하지 않습니다. (주어진 예제에서 당신은 전혀 첫 번째 쿼리를 호출하지 않기 때문에 실제 테스트에서 여러분은 어딘가에 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() 

하지만 그것은 단지 예를 추측하고 그 사이에 몇 가지 추가 로직을 추가 할 계획 된 모든 잠금을 할 이유가 없다 두 번 전화 했어. 당신이 ORM을 사용하는 경우

7

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 
+0

Foo.id == 1234가 있어야합니다. 참조 : http://docs.sqlalchemy.org/en/latest/orm/query.html#sqlalchemy.orm.query.Query.filter – Kapucko

+0

@Kapucko 감사합니다. 편집 됨. –

+0

@MatthewMoisen에서 왜 'add'를 사용하는지 말할 수 있습니까? 만약 내가 그것을 사용하지 않으면, 괜찮을까요? –