Nie mam dużego doświadczenia z SQLAlchemy i mam problem, którego nie mogę rozwiązać. Próbowałem szukać i próbowałem dużo kodu. To jest moja klasa (zredukowana do najbardziej znaczącego kodu):
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 fenoscore matki jest (na przykład) == 10
Jak powiedziano, próbowałem dużo kodu, ale go nie rozumiem. Moim zdaniem logicznym rozwiązaniem byłoby
patients = Patient.query.filter(Patient.mother.phenoscore == 10)
ponieważ możesz uzyskać dostęp .mother.phenoscore
do każdego elementu podczas wyprowadzania, ale ten kod tego nie robi.
Czy istnieje (bezpośrednia) możliwość filtrowania według atrybutu relacji (bez pisania instrukcji SQL lub dodatkowej instrukcji łączenia), potrzebuję tego rodzaju filtra więcej niż jeden raz.
Nawet jeśli nie ma prostego rozwiązania, z przyjemnością otrzymuję wszystkie odpowiedzi.
źródło
has()
obsługuje zarówno wyrażenie warunku jako nienazwany argument, jak i argumentyfilter_by
-stylowe słowa kluczowe. To później wydaje mi się bardziej czytelne.phenoscore = 10
.filter_by
przyjmuje tylko słowa kluczowe równości (ponieważ robi na nich tylko ** kwargs)Musisz sprawdzić relację za pomocą join
Otrzymasz przykład z niniejszych strategii samodzielnego zapytania
źródło
Używałem go z sesjami, ale alternatywnym sposobem bezpośredniego dostępu do pola relacji jest
db_session.query(Patient).join(Patient.mother) \ .filter(Patient.mother.property.mapper.class_.phenoscore==10)
Nie testowałem tego, ale myślę, że to też zadziała
Patient.query.join(Patient.mother) \ .filter(Patient.mother.property.mapper.class_.phenoscore==10)
źródło
Dobra wiadomość dla Ciebie: Niedawno stworzyłem pakiet, który daje Ci filtrowanie / sortowanie za pomocą „magicznych” łańcuchów znaków, jak w Django , więc możesz teraz napisać coś takiego
Patient.where(mother___phenoscore=10)
Jest dużo krótszy, zwłaszcza w przypadku złożonych filtrów, np.
Comment.where(post___public=True, post___user___name__like='Bi%')
Mam nadzieję, że ten pakiet Ci się spodoba
https://github.com/absent1706/sqlalchemy-mixins#django-like-queries
źródło
To jest bardziej ogólna odpowiedź na temat wykonywania zapytań dotyczących relacji.
relationship(..., lazy='dynamic', ...)
Dzięki temu możesz:
parent_obj.some_relationship.filter(ParentClass.some_attr==True).all()
źródło