SqlAlchemy - 관계 속성별 필터링
저는 SQL 화학에 대한 경험이 많지 않고 해결할 수 없는 문제가 있습니다.저는 검색을 시도했고 많은 코드를 시도했습니다.내 클래스입니다(가장 중요한 코드로 축소됨).
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 문 또는 추가 조인 문을 작성하지 않고) 관계의 속성으로 필터링할 수 있는 (직접) 가능성이 있습니까? 이런 종류의 필터가 두 번 이상 필요합니다.
쉬운 해결책이 없더라도 모든 답을 얻을 수 있어 기쁩니다.
관계 방법 사용(가독성 향상):
patients = Patient.query.filter(Patient.mother.has(phenoscore=10))
또는 조인(일반적으로 더 빠름):
patients = Patient.query.join(Patient.mother, aliased=True)\
.filter_by(phenoscore=10)
조인과 관련된 관계를 쿼리해야 합니다.
이 자체 참조 쿼리 전략에서 예제를 얻을 수 있습니다.
좋은 소식입니다: 저는 최근에 장고에서처럼 "마법적인" 문자열로 필터링/정렬을 제공하는 패키지를 만들었습니다. 그래서 이제 당신은 다음과 같은 것을 쓸 수 있습니다.
Patient.where(mother___phenoscore=10)
특히 복잡한 필터의 경우 훨씬 짧습니다.
Comment.where(post___public=True, post___user___name__like='Bi%')
당신이 이 패키지를 즐기길 바랍니다.
https://github.com/absent1706/sqlalchemy-mixins#django-like-queries
세션과 함께 사용했지만 관계 필드에 직접 액세스할 수 있는 다른 방법은
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)
이것은 관계를 쿼리하는 방법에 대한 보다 일반적인 답변입니다.
relationship(..., lazy='dynamic', ...)
이를 통해 다음을 수행할 수 있습니다.
parent_obj.some_relationship.filter(ParentClass.some_attr==True).all()
선언 기반을 사용하여 이 필터를 수행하려는 사용자는 연결 프록시를 사용할 수 있습니다.
from sqlalchemy.ext.associationproxy import association_proxy
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)
"""
Access the associated object(s) through this proxy
Note: Because the above relationship doesn't use a
collection (uselist=False), the associated attribute
will be a scalar. If the relationship does use a
collection (uselist=True), the associated attribute
would then be a list (or other defined collection) of values.
"""
mother_phenoscore = association_proxy('mother', 'phenoscore')
사용하는 대신has()
관계에서 하위 항목을 직접 쿼리할 수 있습니다.
patients = Patient.query.filter(Patient.mother_phenoscore == 10)
관계 열에 필터 쿼리를 추가하려면 'any()' 함수를 사용합니다.
class ArticleModel(db.Model, BaseModel):
__tablename__ = "articles"
id = db.Column(db.Integer, primary_key=True, autoincrement=True)
title = db.Column(db.String(120), nullable=False)
thumbnail = db.Column(db.String(240), nullable=True)
short_content = db.Column(db.String(400), nullable=False)
content = db.Column(db.String, nullable=False)
category_id = db.Column(db.Integer, db.ForeignKey("categories.id"), nullable=False)
category = db.relationship("CategoryModel", backref="articles", lazy=True)
views_count = db.Column(db.Integer, default=0, nullable=False)
comment_count = db.Column(db.Integer, default=0, nullable=False)
comments = db.relationship("CommentModel", backref="articles")
tags = db.relationship("ArticleTagModel", backref="articles", lazy=True)
seo_tags = db.Column(db.String(150), default="Software, Flask, Python, .Net Core, Web, Developer, JavaScript, React, Asp.Net, HTML5, CSS3, Web Development, Mobile, React Native", nullable=False)
seo_description = db.Column(db.String(150), default="", nullable=False)
class ArticleTagModel(db.Model, BaseModel):
__tablename__ = "article_tags"
id = db.Column(db.Integer, primary_key=True, autoincrement=True)
article_id = db.Column(db.Integer, db.ForeignKey("articles.id"), nullable=False)
tag_id = db.Column(db.Integer, db.ForeignKey("tags.id"), nullable=False)
tag = db.relationship("TagModel", backref="article_tags", lazy=True)
이렇게 사용
articles = ArticleModel.query.filter(ArticleModel.tags.any(tag_id=tag_id)).all()
언급URL : https://stackoverflow.com/questions/8561470/sqlalchemy-filtering-by-relationship-attribute
'programing' 카테고리의 다른 글
사전을 만들 때 장고 모델에게 전달할 수 있습니까? (0) | 2023.07.21 |
---|---|
Python 단위 테스트에서 메서드가 호출되었다고 주장합니다. (0) | 2023.07.21 |
PathLib에서 디렉터리를 재귀적으로 제거하시겠습니까? (0) | 2023.07.21 |
문자열의 하위 문자열 테스트 (0) | 2023.07.21 |
@FacesComponent가 있는 JSF 사용자 지정 구성 요소를 SpringBoot에서 찾을 수 없습니다. (0) | 2023.07.21 |