2011-10-21 17 views
5

मैं वाईएएमएल और स्क्लेक्लेमी का उपयोग कर रहा हूं। मैंने अपनी ऑब्जेक्ट को परिभाषित किया है, और मैं इसे ठीक करने के लिए वाईएएमएल का उपयोग करने में सक्षम हूं। हालांकि, जब मैं SQLAlchemy क्वेरी से वापस ऑब्जेक्ट पर YAML का उपयोग करने का प्रयास करता हूं, तो यह त्रुटि can't pickle int objects त्रुटि में विफल रहा है। मैंने एसक्लाक्लेमी से लौटाया गया उदाहरण मुद्रित किया, और यह सही प्रकार दिखा रहा है। मैं कोड को बात करने दूँगा:एसक्यूएलकेमी से ऑब्जेक्ट आने पर int ऑब्जेक्ट त्रुटि नहीं उठा सकता है?

class HashPointer(Base): 
    __tablename__ = 'hash_pointers' 

    id = Column(Integer, primary_key=True) 
    hash_code = Column(VARBINARY(64), unique=True) 
    file_pointer = Column(Text) 

    def __init__(self, hash_code, file_pointer): 
     self.hash_code = hash_code 
     self.file_pointer = file_pointer 

    def __repr__(self): 
     return "<HashPointer('%s', '%s')>" % (self.hash_code, self.file_pointer) 

from sqlalchemy import create_engine 
from sqlalchemy.orm import sessionmaker 
Engine = create_engine("mysql://user:[email protected]/db", echo=True) 
Session = sessionmaker(bind=Engine) 
session = Session() 
fhash = HashPointer(0x661623708235, "c:\\test\\001.txt") 

# PRINTS FINE 
print(yaml.dump(fhash)) 

for instance in session.query(HashPointer).all(): 
    # PRINTS FINE AS __repr__ 
    print instance 

    # THROWS ERROR, 'CAN'T PICKLE INT OBJECTS' 
    print(yaml.dump(instance)) 
+0

"उदाहरण" का प्रकार क्या है? एक yaml.dump (10) ठीक काम करता है, इसलिए मैं एक स्क्लेक्लेमी प्रकार हो सकता हूं जिसमें आवश्यक पिकलिंग विधि नहीं है (यानी।एक __reduce__ विधि जो खुद को पिकलेबल प्रकार देता है)। –

उत्तर

2

कोशिश अपनी कक्षा में निम्नलिखित को जोड़:

def __reduce__(self): 
    'Return state information for pickling' 
    return self.__class__, (int(self.hash_code), str(self.file_pointer)) 
+1

प्रिंट के बाद से मैं उलझन में हूं (yaml.dump (fhash)) ठीक काम करता है, इसलिए यह शिकायत नहीं कर रहा है। किसी क्वेरी से आने पर टाइप क्यों बदल जाएगा? – esac

+0

"प्रिंट उदाहरण" के बाद, "प्रिंट प्रकार (उदाहरण)" डालें। आपको क्या मिलेगा? –

+0

प्रिंट '' – esac

1

ऐसा लगता है कि डिफ़ॉल्ट reduce_ex विधि (आईएम यकीन है कि यह एक है ऑब्जेक्ट() में, लेकिन यह होना आवश्यक नहीं है।) जब आपके पास sqlalchemy सक्रिय है, तो उस रेखा से नीचे आता है, सदस्य में वापस 'राज्य' में सदस्य को कम करता है fall_ex एपीआई जो पीईवाईएएमएल क्रमबद्ध करने के लिए उपयोग करता है।

जब SQLAchechemy क्वेरी से आने वाली ऑब्जेक्ट को क्रमबद्ध करते समय, यह अनिवार्य रूप से ऑब्जेक्ट के मेटाडेटा का एक छिपी हिस्सा है, जो आगे के संचालन के लिए सुलभ है।

यह वह ऑब्जेक्ट है जिसमें PyYAML serializer विफल हो रहा है। आप पीडीबी में अपना सीरियलाइजेशन चलाकर इसे सत्यापित कर सकते हैं, और दो को अपने कॉल स्टैक में represent_object पर कॉल करने के लिए, यहां तक ​​कि अपेक्षाकृत सरल SQLAlchemy क्वेरी ऑब्जेक्ट परिणामों के लिए भी देख सकते हैं।

यह क्वेरी इंस्टेंस लिंक का उपयोग किया जाता है, जैसा कि मैं इसे समझता हूं, पावर विधियों के साथ आपको क्वेरी पर वापस जाने देता है जो किसी दिए गए ऑब्जेक्ट को उसी पायथन दुभाषिया के जीवनकाल से उत्पन्न करता है।

यदि आप उस कार्यक्षमता (session.new & session.dirty जैसी चीजें) की परवाह करते हैं, तो आपको इसके लिए PyYAML के serializer में समर्थन लागू करने की आवश्यकता होगी।

आप परवाह नहीं करते हैं, और सिर्फ अपने घोषित सदस्यों चाहते हैं, तो आप एक आधार वर्ग जो करने के लिए 'खाल' कॉल से कि लिंकेज का उपयोग कर सकते को कम * - ध्यान दें कि यह रूप में SQLAlchemy serializer विस्तार टूट जाएगा हालांकि, इसलिए अपनी योजनाओं को ध्यान से देखें।

एक आधार वर्ग का एक उदाहरण है कि परिवर्तन को लागू करने के लिए है:

DeclBase = declarative_base() 

class Base(DeclBase): 
    __abstract__ = True 

    def __reduce_ex__(self, proto): 
     ret = super(Base, self).__reduce_ex__(proto) 
     ret = (ret[0], ret[1], dict(ret[2])) + ret[3:] 
     ret[2].pop('_sa_instance_state', None) # remove bad yamly from reduce state 
     return ret 

यह तो आप किसी भी लंबित लेन-देन से, इन/YAML से बाहर अपने वस्तुओं roundtrip को हालांकि एक राउंड ट्रिप उन्हें असंबद्ध कर देंगे अनुमति देगा या प्रश्नों। यदि आप एक उदाहरण के लिए आलसी-भारित सदस्यों का उपयोग कर रहे हैं, तो इसमें बातचीत भी हो सकती है। सुनिश्चित करें कि आप जो भी उम्मीद कर रहे हैं उसे क्रमबद्ध कर रहे हैं।

नोट/संपादित करें: मैं यहाँ reduce_ex उपयोग करने के लिए, संभव अन्य आधार वर्ग या mixins के साथ संगत होना करने के लिए चुना है। https://docs.python.org/2/library/pickle.html#object.reduce_ex के अनुसार, यह किसी भी बेस क्लास के लिए सही व्यवहार का उत्पादन करेगा, यह भी पता लगाएगा कि () को कम किया गया था या नहीं।

Redux ... उदाहरण वस्तु के वास्तविक dict वापस आ जाएगी को कम - __reduce * के लिए हां, तो हमें चाहिए वास्तव में उथले प्रतिलिपि कि dict, हम वहां से हटाने के लिए नहीं करना चाहती।

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