2016-08-19 5 views
15

मेरा फ्लास्क-आरामपूर्ण एप्लिकेशन में कई "ऑब्जेक्ट्स" हैं। ऐप के पहले संस्करण में ये सरल डेटा स्ट्रक्चर हैं, जिनमें कोई व्यवहार नहीं है, डिक्ट्स के रूप में लागू किया गया है, या डिस्क्स की सूचियां हैं।गुणों की समानता के लिए SQLAlchemy ऑब्जेक्ट इंस्टेंस की तुलना

इन "ऑब्जेक्ट्स" के गुण बदल सकते हैं। मैं परिवर्तनों को ट्रैक करने के लिए जनरेटर फ़ंक्शन का उपयोग करता हूं, और फिर सर्वर-भेजे गए ईवेंट (एसएसई) के माध्यम से वेब-क्लाइंट को अलर्ट करता हूं। यह ऑब्जेक्ट की "पुरानी" प्रतिलिपि को ट्रैक करने और नवीनतम स्थिति की तुलना करने के द्वारा बनाए रखता है।

ऐप के अगले संस्करण में मैं एसक्यूएलकेमी का उपयोग कर SQLite डीबी से "ऑब्जेक्ट्स" को पॉप्युलेट करता हूं। ऑब्जेक्ट्स अब स्क्लाक्लेमी घोषणात्मक कक्षाओं, या ऐसी कक्षाओं की सूचियों के रूप में लागू किए गए हैं।

गुणों की समानता के आधार पर "पुराने" और "नए" उदाहरणों की तुलना करने के लिए मुझे केवल __eq__ पर मेरे SQLAlchemy ऑब्जेक्ट्स को ओवरराइड करना पड़ा। यानी जब गुणों के समान मान होते हैं तो उदाहरण बराबर/अपरिवर्तित माना जाता है। (मैंने इस प्रश्न के निचले हिस्से में उदाहरण कोड पोस्ट किया है)।

तकनीकी रूप से यह काम करता है, लेकिन कुछ वास्तुशिल्प अलार्म घंटी उठाता है: क्या मैं गलत दिशा में नौकायन कर रहा हूं?

क) मैं SQAlchemy वस्तुओं के लिए __eq__ और __ne__ ओवरराइड जोड़ते हैं, इस कारण एक समस्या SQLAlchemy सकता है जब मैं बाद में वस्तुओं वापस डेटाबेस के लिए फिर से लागू करने के लिए करना चाहते हैं?

बी) एसक्यूएलकेकी वस्तुओं तक पहुंचने के लिए मेरे आवेदन में कितना दूर है: क्या कोई "पायथनिक सर्वोत्तम अभ्यास" है? यानी एसबीएलएलकेमी ऑब्जेक्ट्स को विस्तारित करना सामान्य/सामान्य है जो व्यापार तर्क/व्यवहार के साथ डीबी दृढ़ता से जुड़े हुए हैं (जैसे परिवर्तनों को ट्रैक करना); या उन्हें अन्य वस्तुओं में व्यावसायिक तर्क के साथ डेटाबेस और सर्वर के बीच केवल साधारण डीटीओ के रूप में उपयोग किया जाना चाहिए?

नोट: यह मुझे स्पष्ट है कि आरईएसटी एपिस और एसएसई के माध्यम से ग्राहकों को प्रस्तुत डेटा वेब सर्वर और डीबी में कार्यान्वयन विवरण से समझा जाना चाहिए, ताकि यह इस प्रश्न का हिस्सा न हो।

sqlalchemy id equality vs reference equality https://codereview.stackexchange.com/questions/93511/data-transfer-objects-vs-entities-in-java-rest-server-application http://www.mehdi-khalili.com/orm-anti-patterns-part-4-persistence-domain-model/

class EqualityMixin(object): 
# extended from the concept in : 
# https://stackoverflow.com/questions/390250/elegant-ways-to-support-equivalence-equality-in-python-classes 

    def __eq__(self, other): 
     classes_match = isinstance(other, self.__class__) 
     a, b = deepcopy(self.__dict__), deepcopy(other.__dict__) 
     #compare based on equality our attributes, ignoring SQLAlchemy internal stuff 
     a.pop('_sa_instance_state', None) 
     b.pop('_sa_instance_state', None) 
     attrs_match = (a == b) 
     return classes_match and attrs_match 

    def __ne__(self, other): 
     return not self.__eq__(other) 

उत्तर

1

मैं क्या आधार वर्ग के पीछे क्या हो रहा है, पता चलता है कि __eq__ और __ne__ ओवरराइड ठीक हैं की छानबीन करेंगे। जब आप कक्षा को declarative_base() पर कॉल करके तुरंत चालू करते हैं, तो यह इसे सेट अप करने के लिए दृश्यों के पीछे मेटाक्लास का उपयोग कर रहा है (यह स्पष्ट रूप से समझने के लिए यह स्पष्टीकरण this metaclass explanation पढ़ने के लायक हो सकता है)। यह कुछ कॉन्फ़िगर करने योग्य सेटअप करता है, जैसे कि Base कक्षा में कस्टम कन्स्ट्रक्टर जोड़ने और यह सेट करने से कि यह ऑब्जेक्ट से किसी तालिका में कैसे मैप करेगा।

declarative_base() फिर DeclarativeMeta मेटाक्लास के एक नए Base वर्ग उदाहरण को वापस करने जा रहा है। पूरे कारण मेटाक्लास यहां शामिल हैं ताकि उस समय जब आप एक कक्षा बना सकें जो आपके Base को बढ़ाती है, तो यह इसे किसी तालिका में मैप कर देगी। यदि आप इस पथ को थोड़ा सा रास्ता ढूंढते हैं, तो आप देखेंगे कि यह आपके द्वारा ऑब्जेक्ट पर आपके द्वारा घोषित कॉलम को कैसे तालिका में चिह्नित करता है।

self.cls.__mapper__ = mp_ = mapper_cls(
     self.cls, # cls is your model 
     self.local_table, 
     **self.mapper_args # the columns you have defined 
    ) 

हालांकि वास्तविक मैपर जो इस लगता है कि यह इस स्तर यह प्राथमिक कुंजी और स्तंभों के बजाय वास्तविक वस्तु उदाहरणों के साथ काम कर रहा है पर, बहुत जटिल और निम्न स्तर हो जाता है कर रही है। यह पुष्टि नहीं करता है कि इसका कभी भी उपयोग नहीं किया जाता है, इसलिए, मैंने स्रोत पर == और != के उपयोगों को देखा और चिंता के लिए कोई कारण नहीं देखा।

आपके दूसरे प्रश्न के लिए मैं केवल अपनी राय पेश कर सकता हूं - मैंने इस विषय के आसपास अतीत में कई बार गुमराह किया है और 'गोल्ड स्टैंडर्ड' एसक्यूएल कीमिया उपयोग के तरीके में बहुत कुछ नहीं मिला है। मैंने अब तक कुछ परियोजनाओं के लिए एसक्यूएल कीमिया का उपयोग किया है और ऐसा लगता है कि आपके ऑब्जेक्ट्स का उपयोग तब तक बढ़ सकता है जब तक आप session जीवन-चक्र को समझदारी से दूर कर सकते हैं। मेरे लिए ऐसा लगता है कि कीमिया "जादू" के रूप में पर्याप्त रूप से मॉडलों से अलग किया गया है कि जब सत्र अच्छी तरह से संभाले जाते हैं, तो वे डेटा परत से काफी दूर हटा दिए जाते हैं, ऐसा लगता है कि कक्षाओं में व्यवसाय तर्क की तरह यह नहीं लगेगा रास्ता।

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