2012-12-14 12 views
17

मैं स्क्लेक्लेमी के लिए नया हूं और मूल लेखक तक पहुंच के बिना कुछ हद तक गन्दा कोडबेस प्राप्त किया है।मुझे स्क्लेक्लेमी पर फ्लश() कब कॉल करना चाहिए?

कोड DBSession.flush() पर कॉल के साथ लाइट किया गया है, प्रतीत होता है कि लेखक यह सुनिश्चित करना चाहता था कि डेटा सहेजा जा रहा है। सबसे पहले मैं सिर्फ इस कोड में देखे गए पैटर्न का पालन कर रहा था, लेकिन जैसा कि मैं दस्तावेज़ पढ़ रहा हूं, ऐसा लगता है कि यह अनावश्यक है - ऑटोफ्लशिंग को जगह में होना चाहिए। इसके अतिरिक्त, मुझे कुछ मामलों में एजेक्स कॉल के साथ मिल गया है जो त्रुटि उत्पन्न करते हैं "अवैधRequestError: सत्र पहले से ही फ्लश कर रहा है"।

मैं किस परिदृश्य के तहत वैध रूप से फ्लश() को कॉल करना चाहता हूं?

यह एक पिरामिड अनुप्रयोग है, और SQLAlchemy के साथ स्थापित किया जा रहा है: pyramid_tm साथ संयोजन के रूप में

DBSession = scoped_session(sessionmaker(extension=ZopeTransactionExtension(), expire_on_commit=False)) 
Base = declarative_base() 

उत्तर

26

ZopeTransactionExtensionDBSession पर अपनी परियोजना सब आप के लिए करता है संभाल लेंगे पर सक्रिय किया जा रहा है। जिन परिस्थितियों में आपको फ्लश करने की आवश्यकता है वे हैं:

  • आप एक नई वस्तु बनाना चाहते हैं और प्राथमिक कुंजी वापस लेना चाहते हैं।

    DBSession.add(obj) 
    DBSession.flush() 
    log.info('look, my new object got primary key %d', obj.id) 
    
  • आप एक savepoint में कुछ एसक्यूएल निष्पादित और रोलबैक अगर यह पूरे लेन-देन अमान्य बिना विफल रहता है करने की कोशिश करना चाहते हैं।

    sp = transaction.savepoint() 
    try: 
        foo = Foo() 
        foo.id = 5 
        DBSession.add(foo) 
        DBSession.flush() 
    except IntegrityError: 
        log.error('something already has id 5!!') 
        sp.rollback() 
    

अन्य सभी ORM से जुड़े मामलों में, लेन-देन अपवाद पर आप के लिए निरस्त कर दिया जाएगा, या स्वचालित रूप से pyramid_tm द्वारा सफलता पर प्रतिबद्ध है। यदि आप कच्चे एसक्यूएल निष्पादित करते हैं, तो आपको transaction.commit() स्वयं को निष्पादित करने की आवश्यकता होगी या zope.sqlalchemy.mark_changed(DBSession) के माध्यम से सत्र को गंदे के रूप में चिह्नित करना होगा अन्यथा जेडटीई को सत्र बदलने के लिए कोई रास्ता नहीं है।

True के डिफ़ॉल्ट पर आपको expire_on_commit छोड़ना चाहिए जब तक कि आपके पास वास्तव में कोई अच्छा कारण न हो।

+0

बहुत बहुत धन्यवाद। अनुवर्ती: expire_on_commit = इस सेटअप में गलत होने का वास्तव में एक अच्छा कारण क्या है? (मुझे नहीं पता कि यह पहली जगह क्यों स्थापित किया गया था)। – blocks

+4

मेरे अनुभव में, यह उन लोगों द्वारा उपयोग किया जाता है जो नहीं जानते कि वे क्या कर रहे हैं और प्रतिबद्ध होने के बाद वस्तुओं का उपयोग करके सिस्टम को धोखा देने का प्रयास करें। * जाहिर है * एक प्रतिबद्धता के बाद, आपको कोई गारंटी नहीं है कि उस वस्तु की स्थिति अब मान्य है। –

+0

@ माइकल मरिकेल - बहुत अच्छी तरह से समझाया गया। कैसे हमें फ्लश() का उपयोग नहीं करना चाहिए? [क्या कोड के भीतर SQLAlchemy फ्लश() को कॉल करने से कोई दुष्प्रभाव हैं?] (Http://stackoverflow.com/questions/29338419/are-there-any-side-effects-from-calling-sqlalchemy-flush-within-code) –

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