मैं यह समझने की कोशिश कर रहा हूं कि एक साधारण पढ़ने-योग्य संपत्ति के खिलाफ कैसे मानचित्र करें और जब मैं डेटाबेस में सहेजता हूं तो उस संपत्ति को आग लगती है।SQLAlchemy - केवल पढ़ने के लिए (या गणना की गई) संपत्ति के विरुद्ध मानचित्र कैसे करें
एक प्रदूषित उदाहरण को और अधिक स्पष्ट करना चाहिए। सबसे पहले, एक सरल तालिका:
meta = MetaData()
foo_table = Table('foo', meta,
Column('id', String(3), primary_key=True),
Column('description', String(64), nullable=False),
Column('calculated_value', Integer, nullable=False),
)
मुझे क्या करना केवल पढ़ने के लिए संपत्ति के साथ एक वर्ग है कि मेरे लिए calculated_value स्तंभ में सम्मिलित होगा जब मैं session.commit (फोन की स्थापना की है चाहता हूँ) ...
import datetime
def Foo(object):
def __init__(self, id, description):
self.id = id
self.description = description
@property
def calculated_value(self):
self._calculated_value = datetime.datetime.now().second + 10
return self._calculated_value
SQLAlchemy डॉक्स के अनुसार, मुझे लगता है कि मैं तो इस तरह के नक्शे करना चाहिए:
mapper(Foo, foo_table, properties = {
'calculated_value' : synonym('_calculated_value', map_column=True)
})
इस के साथ समस्या यह है कि _calculated_ है मान तब तक कोई नहीं है जब तक कि आप गणना की गई_अल्यू संपत्ति तक नहीं पहुंच जाते। ऐसा लगता है कि SQLAlchemy डेटाबेस में सम्मिलन पर संपत्ति को कॉल नहीं कर रहा है, इसलिए मुझे इसके बजाय कोई भी मूल्य नहीं मिल रहा है। इसे मैप करने का सही तरीका क्या है ताकि "गणना_value" संपत्ति का परिणाम foo तालिका के "गणना_value" कॉलम में डाला गया हो?
ठीक है - अगर किसी और के पास एक ही प्रश्न है तो मैं इस पोस्ट को संपादित कर रहा हूं। मैं जो कर रहा था वह मैपर एक्सटेंशन का उपयोग कर रहा था। मुझे विस्तार के उपयोग के साथ आपको एक बेहतर उदाहरण दें:
class UpdatePropertiesExtension(MapperExtension):
def __init__(self, properties):
self.properties = properties
def _update_properties(self, instance):
# We simply need to access our read only property one time before it gets
# inserted into the database.
for property in self.properties:
getattr(instance, property)
def before_insert(self, mapper, connection, instance):
self._update_properties(instance)
def before_update(self, mapper, connection, instance):
self._update_properties(instance)
और इस तरह आप इसका उपयोग करते हैं। आइए मान लें कि आपके पास कई कक्षाओं के साथ एक वर्ग है जो केवल डेटाबेस को सम्मिलित करने से पहले आग लगाना चाहिए। मैं यहां मान रहा हूं कि इनमें से प्रत्येक के लिए केवल गुणों को पढ़ा गया है, आपके पास डेटाबेस में एक समान कॉलम है जिसे आप संपत्ति के मूल्य के साथ पॉप्युलेट करना चाहते हैं। तुम अब भी प्रत्येक प्रॉपर्टी के लिए एक पर्याय स्थापित करने के लिए जा रहे हैं, लेकिन आप इसके बाद के संस्करण जब आप वस्तु के नक्शे नक्शाकार एक्सटेंशन का उपयोग:
class Foo(object):
def __init__(self, id, description):
self.id = id
self.description = description
self.items = []
self.some_other_items = []
@property
def item_sum(self):
self._item_sum = 0
for item in self.items:
self._item_sum += item.some_value
return self._item_sum
@property
def some_other_property(self):
self._some_other_property = 0
.... code to generate _some_other_property on the fly....
return self._some_other_property
mapper(Foo, metadata,
extension = UpdatePropertiesExtension(['item_sum', 'some_other_property']),
properties = {
'item_sum' : synonym('_item_sum', map_column=True),
'some_other_property' : synonym('_some_other_property', map_column = True)
})
दिलचस्प।भले ही मैंने इसे थोड़ा अलग तरीके से हल किया, मैंने इसे उत्तर के रूप में चिह्नित किया क्योंकि इसे काम करना चाहिए। जितना अधिक मैं स्क्लाक्लेमी के बारे में सीखता हूं, उतना ही मुझे यह पसंद है! –