2011-12-19 17 views
49

Nie mam zbyt dużego doświadczenia z SQLAlchemy i problemem, którego nie mogę rozwiązać, ale szukam wielu kodu. To moja klasa (zredukowane do najbardziej znaczącego kodzie):SqlAlchemy - Filtrowanie według atrybutów

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) 

i chciałbym zapytać wszystkich pacjentów, których matki phenoscore jest (na przykład) == 10

Jak powiedział, starałem dużo kodu, ale go nie dostaję. Rozwiązanie logicznie, w moich oczach, byłoby

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

ponieważ można uzyskać dostęp .mother.phenoscore dla każdego elementu podczas wyprowadzania, ale ten kod nie zrobić. Czy istnieje (bezpośrednia) możliwość filtrowania według atrybutu relacji (bez pisania instrukcji SQL lub dodatkowej instrukcji join), potrzebuję tego rodzaju filtra więcej niż jeden raz.

Nawet jeśli nie ma prostego rozwiązania, jestem zadowolony wszystkie odpowiedzi

dzięki dużo Christo

Odpowiedz

88

użyć metody has() związku (bardziej czytelne)

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

lub dołączyć (zazwyczaj szybciej):

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

pacjenci = Patient.query.filter (Patient.mother.has (Patient.phenoscore == 1 0)) – user1105851

+0

@ user1105851 'has()' obsługuje zarówno wyrażenie warunkowe jako nienazwany argument, jak i argumenty w stylu słowa "filter_by". Później wydaje mi się bardziej czytelny. –

+0

@DenisOtkidach poprawne, ale wtedy byłoby to 'phenoscore = 10'. 'filter_by' przyjmuje tylko słowa kluczowe równościowe (ponieważ po prostu robi ** kwargs na nich) – aruisdante

2

Dobra wiadomość dla ciebie: ja niedawno pakiet, który umożliwia filtrowanie/sortowania z „magicznych” strun as in Django, więc można teraz napisać coś podobnego

Patient.where(mother___phenoscore=10) 

To dużo krótszy, zwłaszcza w przypadku skomplikowanych filtrów, powiedzmy,

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

Ho pe będziesz cieszyć się ten pakiet

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

1

użyłem go z sesjami, ale alternatywny sposób, gdzie można uzyskać dostęp do pola relacji bezpośrednio jest

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

ja jej nie testowane, ale myślę, to również pracować

Patient.query.join(Patient.mother) \ 
    .filter(Patient.mother.property.mapper.class_.phenoscore==10) 
Powiązane problemy