SqlAlchemy - фильтрация по атрибуту отношения - PullRequest
75 голосов
/ 19 декабря 2011

У меня нет большого опыта работы с 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 или дополнительного оператора соединения), мне нужен фильтр такого типа более одного раза.

Даже если нет простого решения, я с удовольствием получу все ответы.

Ответы [ 4 ]

131 голосов
/ 19 декабря 2011

Используйте метод has() отношения (более читабельно):

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

или объединение (обычно быстрее):

patients = Patient.query.join(Patient.mother, aliased=True)\
                    .filter_by(phenoscore=10)
10 голосов
/ 19 декабря 2011

Вы должны запросить отношенияip с помощью join

. Вы получите пример из этой Стратегии само-ссылочного запроса

2 голосов
/ 17 октября 2017

Я использовал это с сессиями, но альтернативный способ, где вы можете напрямую получить доступ к полю отношений, это

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)
2 голосов
/ 31 марта 2017

Хорошие новости для вас: я недавно сделал пакет, который дает вам фильтрацию / сортировку с «волшебными» строками , как в 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

...