2011-11-29 17 views
15

पर जारी रखने से पहले मेरा एप्लिकेशन उपयोगकर्ताओं को Site ऑब्जेक्ट्स बनाने और हटाने की अनुमति देता है। मैंने इसे session.add() और session.delete() का उपयोग करके कार्यान्वित किया है। इसके बाद मेरे पास 'सेव' और 'रीसेट' बटन हैं जो session.commit() और session.rollback() पर कॉल करते हैं।एक एसक्यूएलकेमी सत्र से किसी ऑब्जेक्ट को

यदि मैं एक नया Site जोड़ता हूं, तो इसे सहेजें/प्रतिबद्ध करें, और फिर इसे हटाएं, सब कुछ ठीक हो जाता है। हालांकि, अगर मैं सहेजे जाने से पहले सत्र से ऑब्जेक्ट को निकालने का प्रयास करता हूं, तो मुझे 'जारी नहीं' त्रुटि मिलती है।

कोड:

self.newSite = Site('foo') 
self.session.add(self.newSite) 
print self.session.new 
self.session.delete(self.newSite) 

आउटपुट:

IdentitySet([<Site('foo')>]) 

Traceback (most recent call last): 
    File "C:\Program Files\Eclipse\dropins\plugins\org.python.pydev.debug_2.2.1.2011071313\pysrc\pydevd_comm.py", line 744, in doIt 
    result = pydevd_vars.evaluateExpression(self.thread_id, self.frame_id, self.expression, self.doExec) 
    File "C:\Program Files\Eclipse\dropins\plugins\org.python.pydev.debug_2.2.1.2011071313\pysrc\pydevd_vars.py", line 375, in evaluateExpression 
    result = eval(compiled, updated_globals, frame.f_locals) 
    File "<string>", line 1, in <module> 
    File "C:\Python27\Lib\site-packages\sqlalchemy\orm\session.py", line 1245, in delete 
    mapperutil.state_str(state)) 
InvalidRequestError: Instance '<Site at 0x1ed5fb0>' is not persisted 

मैं समझता हूँ कि यहाँ क्या हो रहा है, लेकिन मुझे यकीन है कि मैं क्या बजाय करना चाहिए नहीं कर रहा हूँ।

क्या सत्र से एक अभी तक जारी वस्तु को हटाने का कोई अन्य तरीका है? या क्या मुझे हटाने की कोशिश करने से पहले session.flush() पर कॉल करना चाहिए, अगर मैं जिस वस्तु को हटाना चाहता हूं, उसे अभी तक फ़्लश नहीं किया गया है?

यदि यह बाद वाला है, तो session.query() ऑटो-फ्लश (सुनिश्चित करें कि लंबित वस्तुएं क्वेरी परिणामों में दिखाई देती हैं) सुनिश्चित करें, लेकिन session.delete() नहीं (जो सुनिश्चित करेगा कि लंबित वस्तुओं को बिना त्रुटि के हटाया जा सकता है)।

उत्तर

13

आप Session.expunge() कर सकते हैं। मुझे लगता है कि delete() के साथ तर्क यह है कि, यह चिंता है कि यदि आप इसे लंबित भेजते हैं तो आप चीजों का ट्रैक नहीं रख रहे हैं। लेकिन मैं उस कहानी के दूसरी तरफ देख सकता हूं, मैं इसके बारे में सोचूंगा। असल में delete() द्वारा निहित राज्य में दृढ़ता की कुछ धारणाएं शामिल हैं लेकिन संभवतः वे उतनी महत्वपूर्ण नहीं हैं जितनी मैं सोच रहा हूं। एक "निष्कासित या हटाएं" विधि तब दिमाग में आती है, जो मजाकिया है कि मूल रूप से "सहेजने या अपडेट" मूल रूप से हम हाइबरनेट से कॉपी करते हैं, जो अभी "एड" बन गया है। "जोड़ें" क्षणिक-> लंबित के साथ-साथ अलग-अलग-> लगातार - क्या एक संभावित "निकालें()" लंबित दोनों>> क्षणिक और लगातार-> हटाया जा सकता है? बहुत खराब स्कॉप्ड सत्र में पहले से ही "निकालें()" है ....

Session.query() autoflushes क्योंकि यह कुछ पंक्तियों को प्राप्त करने के लिए कुछ एसक्यूएल उत्सर्जित करने के लिए डेटाबेस में जाने वाला है; तो जो भी आपको स्थानीय रूप से पहले बाहर जाना है। delete() बस किसी ऑब्जेक्ट की स्थिति को चिह्नित करता है इसलिए किसी भी SQL को आमंत्रित करने की आवश्यकता नहीं है। अगर हम लंबित पर काम करने के लिए delete() चाहते थे, तो हम केवल उस दावे को बदल देंगे।

दिलचस्प बात यह है कि यदि आप rollback() सत्र में, जो भी add() 'उस सत्र में एड है, चाहे वह फ़्लश हो गया हो या नहीं, समाप्त हो गया है।

+3

मैं माइक से सहमत हूं कि 'हटाएं' अधिक क्षमाशील हो सकता है। हालांकि, वर्तमान स्थिति बहुत सरल है - अन्य संबंधित वस्तुएं हो सकती हैं जो स्पष्ट रूप से या निहित रूप से (संबंधों के माध्यम से) एक ही सत्र में जोड़े गए थे और नहीं। इसलिए, आईएमओ, सबसे साफ तरीका सत्र पर 'रोलबैक() 'करना है। – van

+0

धन्यवाद, यह अब समझ में आता है। तो जब डिलीट बटन क्लिक किया जाता है, तो तर्क क्या होना चाहिए? कुछ कोशिश करें 'session :de.delete (foo); InvalidRequestError को छोड़कर: session.expunge (foo) '? या, [इस उत्तर] के अनुसार (http://stackoverflow.com/a/3897845/665488), शायद: 'if_identity (foo): session.delete (foo); अन्य: session.expunge (foo) '? –

+5

मैं शायद कहूंगा "अगर सत्र में ऑब्जेक्ट। नया: एक्सप्लोर करें: हटाएं" – zzzeek

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