Ich habe nicht viel Erfahrung mit SQLAlchemy und ich habe ein Problem, das ich nicht lösen kann. Ich habe versucht zu suchen und ich habe viel Code ausprobiert. Dies ist meine Klasse (auf den wichtigsten Code reduziert):
class Patient(Base):
__table= '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)
und ich möchte alle Patienten befragen, deren Mutters Phenoscore ist (zum Beispiel) == 10
Wie gesagt, ich habe viel Code ausprobiert, aber ich verstehe ihn nicht. Die logische Lösung wäre in meinen Augen
patients = Patient.query.filter(Patient.mother.phenoscore == 10)
sie können bei der Ausgabe für jedes Element auf .mother.phenoscore
zugreifen, dieser Code tut dies jedoch nicht.
Gibt es eine (direkte) Möglichkeit, nach einem Attribut einer Beziehung zu filtern (ohne die SQL-Anweisung oder eine zusätzliche Join-Anweisung zu schreiben), benötige ich diese Art von Filter mehr als einmal.
Auch wenn es keine einfache Lösung gibt, freue ich mich über alle Antworten.
Verwenden Sie die Methode has()
der Beziehung (besser lesbar):
patients = Patient.query.filter(Patient.mother.has(phenoscore=10))
oder beitreten (normalerweise schneller):
patients = Patient.query.join(Patient.mother, aliased=True)\
.filter_by(phenoscore=10)
Sie müssen die Beziehung zu join abfragen
Sie erhalten daraus das Beispiel Self-Referential Query Strategies
Gute Nachrichten für Sie: Ich habe kürzlich ein Paket erstellt, mit dem Sie mit "magischen" Zeichenfolgen filtern/sortieren können wie in Django , sodass Sie jetzt so etwas wie schreiben können
Patient.where(mother___phenoscore=10)
Es ist viel kürzer, vor allem für komplexe Filter, sagen wir,
Comment.where(post___public=True, post___user___name__like='Bi%')
Ich hoffe, Sie werden dieses Paket genießen
https://github.com/absent1706/sqlalchemy-mixins#Django-like-queries
Ich habe es bei Sitzungen verwendet, aber eine andere Möglichkeit, direkt auf das Beziehungsfeld zuzugreifen, ist
db_session.query(Patient).join(Patient.mother) \
.filter(Patient.mother.property.mapper.class_.phenoscore==10)
Ich habe es nicht getestet, aber ich denke, das würde auch funktionieren
Patient.query.join(Patient.mother) \
.filter(Patient.mother.property.mapper.class_.phenoscore==10)