2011-10-25 14 views
25

मैं परिणाम के बिना किसी फ़िल्टर किए गए क्वेरी का उपयोग कर कुछ बच्चे पंक्तियां हटाना कोशिश कर रहा हूँ:SQLAlchemy हटाना सबक्वेरी

sl = DBSession.query(Puesto.id).filter(Puesto.locales_id == id).subquery() 
DBSession.query(Servicio).filter(Servicio.puestos_id.in_(sl)).delete() 

मैं त्रुटि के रूप में InvalidRequestError: Could not evaluate current criteria in Python. Specify 'fetch' or False for the synchronize_session parameter. हो रही है।

पूर्ण स्टैक ट्रेस: ​​

Traceback (most recent call last): 
    File "/usr/src/tg2env/ceaf/ceaf/controllers/root.py", line 1673, in delete_local 
    DBSession.query(Servicio).filter(Servicio.puestos_id.in_(sl)).delete() 
    File "/usr/src/tg2env/lib/python2.4/site-packages/SQLAlchemy-0.6.6-py2.4.egg/sqlalchemy/orm/query.py", line 2126, in delete 
    raise sa_exc.InvalidRequestError(
InvalidRequestError: Could not evaluate current criteria in Python. Specify 'fetch' or False for the synchronize_session parameter. 

मैं कहाँ समस्या है खोजने के लिए सक्षम नहीं हो रहा हूँ ...

किसी भी विचार?

सादर

उत्तर

53

स्रोत में देख जहाँ आपके अपवाद तब होता है के बाद मैं इस कोशिश कर सुझाव देते हैं:

sl = DBSession.query(Puesto.id).filter(Puesto.locales_id == id).subquery() 
DBSession.query(Servicio).filter(Servicio.puestos_id.in_(sl)) \ 
.delete(synchronize_session='fetch') 

इसका क्या मतलब के लिए documentation of the delete method देखें। fetch तर्क पास करने से मूल रूप से दो बार क्वेरी को चलाया जाएगा, एक बार चयन के रूप में और एक बार हटाए जाने के रूप में।

तो दो क्वेरी चलाने वांछित नहीं है, synchronize_session=False बजाय पारित और फिर session.expire_all() फोन के तुरंत बाद MetaData दुकान के भीतर avoid having inconsistent state को हटा दें।

+0

पहला दृष्टिकोण बहुत अच्छा काम करता है। अब synchronize_session = 'मूल्यांकन' के साथ क्यों काम कर रहे हैं? – LooPer

+1

चूंकि डिलीट सबक्वायरी के साथ 'in_' का उपयोग करता है, इसलिए 'मेटाडेटा' के लिए 'चयन' क्वेरी आवश्यक है कि यह तय करने के लिए कि इसकी कौन सी मेमोरी ऑब्जेक्ट समाप्त हो गई है। इस विकल्प को पास करने से यह करने की अनुमति मिलती है। बिना शर्त तरीके से ऐसा करने से कुछ स्थितियों में खराब प्रदर्शन होगा। – wberry

+2

यह दस्तावेज़ यह भी कहता है कि अगर हम तुरंत प्रतिबद्ध करते हैं, तो हमें autocommit = झूठी के साथ session.expire_all() को कॉल करने की आवश्यकता नहीं है। – giga