SqlAlchemy - संबंध विशेषता द्वारा फ़िल्टरिंग


94

मुझे SQLAlchemy के साथ बहुत अनुभव नहीं है और मुझे एक समस्या है, जिसे मैं हल नहीं कर सकता। मैंने खोज करने की कोशिश की और मैंने बहुत सारे कोड की कोशिश की। यह मेरी कक्षा है (सबसे महत्वपूर्ण कोड तक कम):

class Patient(Base):
    __tablename__ = 'patients'
    id = Column(Integer, primary_key=True, nullable=False)
    mother_id = Column(Integer, ForeignKey('patients.id'), index=True)
    mother = relationship('Patient', primaryjoin='Patient.id==Patient.mother_id', remote_side='Patient.id', uselist=False)
    phenoscore = Column(Float)

और मैं उन सभी रोगियों को क्वेरी करना चाहूँगा, जिनकी माँ का फेनोकोर है (उदाहरण के लिए) == 10

जैसा कि कहा गया है, मैंने बहुत सारे कोड की कोशिश की, लेकिन मुझे यह नहीं मिला। मेरी नजर में तार्किक समाधान, होगा

patients = Patient.query.filter(Patient.mother.phenoscore == 10)

क्योंकि, आप .mother.phenoscoreआउटपुट करते समय प्रत्येक तत्व तक पहुँच सकते हैं लेकिन, यह कोड ऐसा नहीं करता है।

क्या किसी रिश्ते की विशेषता (SQL स्टेटमेंट, या एक अतिरिक्त जॉइन-स्टेटमेंट लिखे बिना) द्वारा फ़िल्टर करने की एक (प्रत्यक्ष) संभावना है, मुझे एक से अधिक बार इस तरह के फिल्टर की आवश्यकता है।

अगर कोई आसान उपाय नहीं है, तो भी मैं सभी जवाब पाकर खुश हूं।

जवाबों:


169

has()रिश्ते की विधि का उपयोग करें (अधिक पठनीय):

patients = Patient.query.filter(Patient.mother.has(phenoscore=10))

या शामिल हों (आमतौर पर तेज़):

patients = Patient.query.join(Patient.mother, aliased=True)\
                    .filter_by(phenoscore=10)

9
रोगियों = Patient.query.filter (Patient.mother.has (Patient.phenoscore == 10))
user1105851

@ user1105851 has()अनाम तर्क और -स्टाइल filter_byकीवर्ड तर्क के रूप में दोनों स्थिति अभिव्यक्ति का समर्थन करता है। बाद में मुझे अधिक पठनीय लगता है।
डेनिस ओटकिडैक

@DenisOtkidach सही है, लेकिन तब यह होगा phenoscore = 10filter_byकेवल समानता वाले कीवर्ड लेता है (क्योंकि यह सिर्फ उन पर ** kwargs कर रहा है)
aruisdante

@aruisdante आप सही हैं, यह उत्तर का गलत संपादन था।
डेनिस ओटकिडैक

4
का उपयोग किसी भी बजाय: रोगियों = Patient.query.filter (Patient.mother.any (phenoscore = 10))
बोस्टन Kenne


7

मैंने इसे सत्रों के साथ उपयोग किया था, लेकिन एक वैकल्पिक तरीका है जहां आप सीधे संबंध क्षेत्र तक पहुंच सकते हैं

db_session.query(Patient).join(Patient.mother) \
    .filter(Patient.mother.property.mapper.class_.phenoscore==10)

मैंने इसका परीक्षण नहीं किया है, लेकिन मुझे लगता है कि यह भी काम करेगा

Patient.query.join(Patient.mother) \
    .filter(Patient.mother.property.mapper.class_.phenoscore==10)

5

आपके लिए अच्छी खबर है: मैंने हाल ही में पैकेज बनाया है जो आपको "जादुई" तार के साथ छानने / छाँटने की सुविधा देता है जैसे कि Django में , इसलिए अब आप कुछ ऐसा लिख ​​सकते हैं

Patient.where(mother___phenoscore=10)

यह बहुत छोटा है, विशेष रूप से जटिल फिल्टर के लिए, कहते हैं,

Comment.where(post___public=True, post___user___name__like='Bi%')

आशा है कि आप इस पैकेज का आनंद लेंगे

https://github.com/absent1706/sqlalchemy-mixins#django-like-queries


0

यह रिश्तों को क्वेरी करने के बारे में अधिक सामान्य उत्तर है।

relationship(..., lazy='dynamic', ...)

यह आपको इसकी अनुमति देता है:

parent_obj.some_relationship.filter(ParentClass.some_attr==True).all()
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.