2012-04-09 12 views
13

मैं SQLAlchemy में अद्यतन के लिए चयन का उपयोग करने का एक पूरा उदाहरण ढूंढ रहा हूं, लेकिन एक googling नहीं मिला है। मैं निम्नलिखित कोड (ब्लॉक हमेशा के लिए) काम नहीं करता है एक ही पंक्ति ताला और एक स्तंभ अद्यतन करने की आवश्यकता: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

यह उत्तर दिए गए प्रश्न के मुख्य बिंदु को याद करता है, जो 'चयन ... अद्यतन के लिए उपयोग उदाहरण' है। इसे से कोड प्रस्तावित रूप में घटाया जा सकता है, लेकिन फिर यह अनुरोधित निर्माण का उपयोग नहीं करता है। बेशक अगर @ लॉक लॉक प्राप्त करने और रिकॉर्ड अपडेट करने के बीच कोई अतिरिक्त तर्क जोड़ने की योजना नहीं बना रहा है, तो इस तरह की कमी पूरी तरह ठीक है। – 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() 

जैसे साधारण मामले में बेशक किसी भी ताला ऐसा करने के लिए, लेकिन मुझे लगता है कि यह केवल उदाहरण है और आप उन लोगों के बीच कुछ अतिरिक्त तर्क जोड़ने की योजना बना रहे थे कोई कारण नहीं है दो कॉल

7

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

Foo.id == 1234 होना चाहिए। संदर्भ: http://docs.sqlalchemy.org/en/latest/orm/query.html#sqlalchemy.orm.query.Query.filter – Kapucko

+0

@ कपाको धन्यवाद; संपादित। –

+0

@ मैथ्यूमोइसेन क्या आप मुझे बता सकते हैं कि 'add' का उपयोग क्यों करें? अगर मैं इसका इस्तेमाल नहीं करता, तो क्या यह ठीक रहेगा? –

संबंधित मुद्दे