SqlAlchemy-관계 특성으로 필터링


94

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)

어머니의 phenoscore가 (예를 들어) 인 모든 환자를 쿼리하고 싶습니다. == 10

말했듯이 많은 코드를 시도했지만 이해하지 못했습니다. 내 눈에 논리적으로 해결책은

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

.mother.phenoscore출력 할 때 각 요소에 액세스 할 수 있지만이 코드는이를 수행하지 않기 때문입니다.

관계의 속성으로 필터링 할 수있는 (직접) 가능성이 있습니까 (SQL 문 또는 추가 조인 문을 작성하지 않고), 이러한 종류의 필터가 두 번 이상 필요합니다.

쉬운 해결책이 없더라도 모든 답을 얻을 수있어서 기쁩니다.

답변:


169

has()관계 방법 사용 (더 읽기 쉬움) :

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

또는 가입 (일반적으로 더 빠름) :

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

9
환자 = Patient.query.filter (Patient.mother.has (Patient.phenoscore == 10))
user1105851

@ user1105851 has()은 명명되지 않은 인수와 filter_by스타일 키워드 인수 로 조건식을 모두 지원합니다 . 나중에는 더 읽기 쉬운 것 같습니다.
Denis Otkidach

@DenisOtkidach 정확하지만 phenoscore = 10. filter_by평등 키워드 만 사용합니다 (** kwargs를 수행하기 때문에)
aruisdante

@aruisdante 당신이 맞습니다, 그것은 대답의 잘못된 편집이었습니다.
Denis Otkidach 2014

4
사용할 수 있는 대신 : 환자 = Patient.query.filter (Patient.mother.any (phenoscore = 10))
보스턴 Kenne


7

세션과 함께 사용했지만 관계 필드에 직접 액세스 할 수있는 다른 방법은

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)

5

좋은 소식이 있습니다. 저는 최근 에 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


0

이것은 관계를 쿼리하는 방법에 대한보다 일반적인 대답입니다.

relationship(..., lazy='dynamic', ...)

이를 통해 다음을 수행 할 수 있습니다.

parent_obj.some_relationship.filter(ParentClass.some_attr==True).all()
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.