Подтвердить что ты не робот

SqlAlchemy - Фильтрация по атрибуту отношения

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

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

4b9b3361

Ответ 1

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

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

или присоединиться (обычно быстрее):

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

Ответ 3

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

Ответ 4

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

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)