2010-06-14 13 views
36

मैंने अभी स्क्लेक्लेमी का उपयोग शुरू किया और एक डिटेक्टेड इंस्टेंस एरर प्राप्त किया और कहीं भी इस पर अधिक जानकारी नहीं मिल पाई। मैं एक सत्र के बाहर उदाहरण का उपयोग कर रहा हूं, इसलिए यह स्वाभाविक है कि SQLAlchemy किसी भी रिश्ते को लोड करने में असमर्थ है अगर वे पहले से लोड नहीं हैं, हालांकि, जो विशेषता मैं एक्सेस कर रहा हूं वह संबंध नहीं है, वास्तव में इस ऑब्जेक्ट का कोई संबंध नहीं है। मुझे उत्सुक लोडिंग जैसे समाधान मिलते हैं, लेकिन मैं इस पर लागू नहीं हो सकता क्योंकि यह कोई संबंध नहीं है। मैंने सत्र बंद करने से पहले इस विशेषता को "स्पर्श" करने का भी प्रयास किया, लेकिन यह अभी भी अपवाद को रोकता नहीं है। गैर-रिलेशनल प्रॉपर्टी के लिए इस अपवाद को एक बार पहले सफलतापूर्वक एक्सेस करने के बाद क्या हो सकता है? इस मुद्दे को डीबग करने में कोई मदद की सराहना की जाती है। मैं इस बीच एक पुन: उत्पन्न स्टैंड-अलोन परिदृश्य पाने और यहां अपडेट करने का प्रयास करूंगा।नियमित विशेषता के साथ SQLAlchemy DetachedInstance त्रुटि (संबंध नहीं)

अद्यतन:

File "/home/hari/bin/lib/python2.6/site-packages/SQLAlchemy-0.6.1-py2.6.egg/sqlalchemy/orm/attributes.py", line 159, in __get__ 
    return self.impl.get(instance_state(instance), instance_dict(instance)) 
    File "/home/hari/bin/lib/python2.6/site-packages/SQLAlchemy-0.6.1-py2.6.egg/sqlalchemy/orm/attributes.py", line 377, in get 
    value = callable_(passive=passive) 
    File "/home/hari/bin/lib/python2.6/site-packages/SQLAlchemy-0.6.1-py2.6.egg/sqlalchemy/orm/state.py", line 280, in __call__ 
    self.manager.deferred_scalar_loader(self, toload) 
    File "/home/hari/bin/lib/python2.6/site-packages/SQLAlchemy-0.6.1-py2.6.egg/sqlalchemy/orm/mapper.py", line 2323, in _load_scalar_attributes 
    (state_str(state))) 
DetachedInstanceError: Instance <ReportingJob at 0xa41cd8c> is not bound to a Session; attribute refresh operation cannot proceed 

आंशिक मॉडल इस तरह दिखता है:

metadata = MetaData() 
ModelBase = declarative_base(metadata=metadata) 

class ReportingJob(ModelBase): 
    __tablename__ = 'reporting_job' 

    job_id   = Column(BigInteger, Sequence('job_id_sequence'), primary_key=True) 
    client_id  = Column(BigInteger, nullable=True) 

और क्षेत्र client_id क्या एक साथ इस अपवाद उत्पन्न कर रहा है है यह कुछ के ढेर के साथ वास्तविक अपवाद संदेश है नीचे की तरह उपयोग:

क्वेरी:

jobs = session \ 
      .query(ReportingJob) \ 
      .filter(ReportingJob.job_id == job_id) \ 
      .all() 
    if jobs: 
     # FIXME(Hari): Workaround for the attribute getting lazy-loaded. 
     jobs[0].client_id 
     return jobs[0] 

यह वही सत्र दायरे से बाहर बाद में अपवाद से चलाता है:

 msg = msg + ", client_id: %s" % job.client_id 
+0

यह मदद कर सकता है: http://stackoverflow.com/a/25694346/134904 – kolypto

उत्तर

53

मैं मूल कारण पाया कोड है कि अपवाद के कारण होता है को कम करने का प्रयास करते। सत्र के बंद होने के बाद मैंने अलग-अलग स्थानों पर एक ही विशेषता पहुंच कोड रखा और पाया कि यह निश्चित रूप से क्वेरी सत्र के बंद होने के तुरंत बाद किसी भी समस्या का कारण नहीं बनता है। यह पता चला है कि वस्तु को अद्यतन करने के लिए खोला गया एक नया सत्र बंद करने के बाद समस्या प्रकट हो रही है। एक बार जब मुझे समझ में आया कि ऑब्जेक्ट की स्थिति एक सत्र के करीब अनुपयोगी है, तो मैं इस thread को खोजने में सक्षम था जिसने इस मुद्दे पर चर्चा की। दो समाधान है कि धागा से बाहर आ रहे हैं:

  • एक सत्र खुला रखें (जो स्पष्ट है)
  • sessionmaker() करने के लिए expire_on_commit=False निर्दिष्ट करें। session.expire_on_commit = False:

3 विकल्प मैन्युअल रूप से सत्र पर False को expire_on_commit स्थापित करने के लिए एक बार यह बनाया जाता है, कुछ की तरह है। मैंने सत्यापित किया कि यह मेरी समस्या हल करता है।

+4

क्या 'session.expunge_all()' मदद करेगा? – Sardathrion

+0

यह कैसे मदद करता है? ऐसा लगता है कि वास्तव में लोड की गई सभी वस्तुओं का सत्र साफ़ हो जाता है। – haridsv

+0

'session.expire_on_commit = गलत 'खराब है, क्योंकि यदि डेटाबेस ने मानों को कुछ रूपांतरित कर दिया है, तो आप इसे कभी नहीं जानते होंगे – kolypto

8

हमें expire_on_commit के साथ False पर भी इसी तरह की त्रुटियां मिल रही थीं। अंत में यह वास्तव में दो sessionmaker एस होने के कारण हुआ था जो दोनों अलग-अलग अनुरोधों में सत्र बनाने के लिए उपयोग किए जा रहे थे। मैं वास्तव में समझ नहीं पा रहा था कि क्या हो रहा था, लेकिन यदि आप expire_on_commit=False के साथ यह अपवाद देखते हैं, तो सुनिश्चित करें कि आपके पास दो sessionmaker प्रारंभ नहीं हैं।

0

मेरे लिए (नौसिखिया), मैंने इंडेंट पर गलती की और मेरे लूप के अंदर सत्र बंद कर दिया, जिसमें मैं प्रत्येक पंक्ति लूप करता हूं, कुछ ऑपरेशन करता हूं और हर बार प्रतिबद्ध करता हूं।

तो मेरे जैसे उन नौसिखियों के लिए, expire_on_commit=False जैसी चीजों को सेट करने से पहले अपना कोड जांचें, इससे आपको एक और जाल हो सकता है।

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