मैं जानना चाहता हूं कि डेटाबेस में एक परिकलित मूल्य को साफ तरीके से कैसे सहेजना है:

एक उदाहरण (SQLAlchemy मैनुअल से लिया गया):

Base = declarative_base()

class Interval(Base):
    __tablename__ = 'interval'

    id = Column(Integer, primary_key=True)
    start = Column(Integer)
    end = Column(Integer)

    @hybrid_property
    def length(self):
        return self.end - self.start

तो length की गणना की जाती है। लेकिन आसान क्वेरी लुक-अप (किसी अन्य डेटाबेस टूल में) के लिए, मैं चाहता हूं कि यह length तालिका में भी सहेजा जाए।

तो मेरा पहला कच्चा परीक्षण बस जोड़ना था: length = Column(Float)। जाहिर है यह काम नहीं करता है (लेकिन मैंने सोचा कि मैं इसे फिर भी कोशिश करूंगा: पी) क्योंकि लंबाई-विधि लंबाई-कॉलम को ओवरराइट करती है।

अभी मेरा एकमात्र तरीका है जिसके बारे में मैं सोच सकता हूं कि इसे init और defer to super() में इस तरह से गणना करना है:

Base = declarative_base()

class Interval(Base):
    __tablename__ = 'interval'

    id = Column(Integer, primary_key=True)
    start = Column(Integer)
    end = Column(Integer)
    length = Column(Integer)

    def __init__(self, *args, **kwargs):
        kwargs['length'] = kwargs['end'] - kwargs['start']
        super().__init__(*args, **kwargs)

हालांकि, मुझे लगता है कि एक क्लीनर तरीका होना चाहिए। है?

धन्यवाद!

0
Steven Van Ingelgem 13 सितंबर 2020, 14:39

2 जवाब

सबसे बढ़िया उत्तर

इसे संभालने के कई तरीके हैं।

एक है before_update और before_insert ट्रिगर। ये एक SQLAlchemy चीज हैं जहां एक मॉडल में परिवर्तन स्वचालित रूप से पहचाने जाते हैं, और सर्वर पर पंक्तियों को लिखे जाने से पहले ईवेंट भेज दिए जाते हैं। फिर आप इसका उपयोग सेव को पूर्व-खाली करने के लिए कर सकते हैं, संभावित रूप से देख सकते हैं कि कौन से कॉलम बदल गए हैं, और फिर तदनुसार length अपडेट करें।

दूसरा generated या computed column का उपयोग कर रहा है। इन्हें [Postgres 12](जेनरेट किए गए कॉलम में पेश किया गया है ), और वे MySQL, Oracle, और MS SQL सर्वर में भी मौजूद हैं - हालाँकि मैं इसके बारे में कम जानता हूँ। वे अनिवार्य रूप से वही काम करते हैं, लेकिन आप उस तर्क को अपनी तालिका परिभाषा में जोड़ते हैं और आप इसके बारे में भूलने के लिए स्वतंत्र हैं। SQLAlchemy 1.3.11 के रूप में उनका समर्थन करता है।

2
Ruben Helsloot 13 सितंबर 2020, 16:50

आप column_property< का इस्तेमाल कर सकते हैं /strong> इसके बजाय sqlalchemy में सुविधा hybrid_property है।

column_property: column_property() फ़ंक्शन का उपयोग SQL एक्सप्रेशन को नियमित रूप से मैप किए गए कॉलम के समान तरीके से मैप करने के लिए किया जा सकता है। इस तकनीक के साथ, लोड समय पर विशेषता को अन्य सभी कॉलम-मैप किए गए विशेषताओं के साथ लोड किया जाता है।

नोट: आप column_property पर query भी कर सकते हैं।

Base = declarative_base()

class Interval(Base):
    __tablename__ = 'interval'

    id = Column(Integer, primary_key=True)
    start = Column(Integer)
    end = Column(Integer)
    length = column_property(end - start)

क्वेरी उदाहरण:

session.query(Interval).filter(Interval.length == 10)
0
Mohammad Sheikhian 13 सितंबर 2020, 22:03