SqlAlchemy - İlişki Özelliğine Göre Filtreleme


98

SQLAlchemy ile fazla tecrübem yok ve çözemediğim bir problemim var. Aramayı denedim ve çok sayıda kod denedim. Bu benim Sınıfım (en önemli koda indirgenmiştir):

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)

ve annesinin fenoscoreu olan tüm hastaları sorgulamak istiyorum (örneğin) == 10

Söylendiği gibi, çok fazla kod denedim ama anlamıyorum. Benim gözümde mantıksal olarak çözüm,

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

çünkü çıktı .mother.phenoscorealırken her elemana erişebilirsiniz , ancak bu kod bunu yapmaz.

Bir ilişkinin özniteliğine göre filtreleme (doğrudan) imkanı var mı (SQL İfadesi veya ekstra birleştirme ifadesi yazmadan), bu tür bir filtreye birden fazla kez ihtiyacım var.

Kolay bir çözüm olmasa bile tüm cevapları almaktan mutluluk duyarım.

Yanıtlar:


176

has()İlişki yöntemini kullanın (daha okunaklı):

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

veya katıl (genellikle daha hızlı):

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

9
hastalar = Patient.query.filter (Patient.mother.has (Patient.phenoscore == 10))
user1105851

@ user1105851 has(), adsız bağımsız değişken olarak koşul ifadesini ve- filter_bytarzı anahtar kelime bağımsız değişkenlerini destekler. Sonrası bana daha okunaklı görünüyor.
Denis Otkidach

@DenisOtkidach doğru, ama o zaman olur phenoscore = 10. filter_byyalnızca eşitlik anahtar kelimeleri alır (üzerlerine sadece ** kwargs yaptığı için)
aruisdante

@aruisdante Haklısın, cevabın hatalı bir şekilde düzenlenmesi.
Denis Otkidach

5
kullanmak herhangi yerine: hasta = Patient.query.filter (Patient.mother.any (phenoscore = 10))
Boston Kenne


7

Oturumlarda kullandım, ancak ilişki alanına doğrudan erişmenin alternatif bir yolu da

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

Test etmedim ama sanırım bu da işe yarayacak

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


1

Bu, ilişkilerin nasıl sorgulanacağına dair daha genel bir cevaptır.

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

Bu, şunları yapmanızı sağlar:

parent_obj.some_relationship.filter(ParentClass.some_attr==True).all()
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.