programing

SQLLlchemy: 적어도 하나의 다대다 관련 테이블에서 멤버 자격으로 필터링

minimums 2023. 10. 15. 17:10
반응형

SQLLlchemy: 적어도 하나의 다대다 관련 테이블에서 멤버 자격으로 필터링

SQLLchemy 0.7.1과 MySQL 5.1 데이터베이스를 사용하여 다음과 같이 다대다 관계를 설정했습니다.

user_groups = Table('user_groups', Base.metadata,
    Column('user_id', String(128), ForeignKey('users.username')),
    Column('group_id', Integer, ForeignKey('groups.id'))
)

class ZKUser(Base, ZKTableAudit):
    __tablename__ = 'users'

    username   = Column(String(128), primary_key=True)
    first_name = Column(String(512))
    last_name  = Column(String(512))

    groups = relationship(ZKGroup, secondary=user_groups, backref='users')

class ZKGroup(Base, ZKTableAudit):
    __tablename__ = 'groups'

    id          = Column(Integer, primary_key=True)
    name        = Column(String(512))

사용자는 여러 그룹에 속할 수 있고, 그룹에는 여러 사용자가 속할 수 있습니다.

제가 하려는 일은 그룹 목록에서 적어도 하나의 그룹에 속한 사용자만 반환하는 SQLAlchemy 쿼리를 구축하는 것입니다.

나는 그들과 놀았습니다.in_함수이지만, 이는 목록의 구성원 자격에 대한 스칼라 값을 검정할 때만 작동하는 것으로 보입니다.저는 SQL 작가가 아니기 때문에 어떤 종류의 사람인지조차 모릅니다.SELECT이것은 필요한 진술입니다.

많은 연구 끝에, 저는 SQL 용어에 대한 저 자신의 무지가 저의 발목을 잡고 있다는 것을 깨달았습니다.그룹 목록의 "최소한 하나"에 속하는 사용자를 찾기 위한 해결책을 찾는 것은 그룹 목록의 "임의"에 속하는 사용자를 찾는 것이어야 했습니다.anySQLAlchemy의 ORM 기능은 다음과 같이 내가 필요로 했던 것을 정확히 수행합니다.

session.query(ZKUser).filter(ZKUser.groups.any(ZKGroup.id.in_([1,2,3])))

이 코드는 (MySQL 5.1에서) 다음과 같은 SQL을 내보냅니다.

SELECT * FROM users 
WHERE EXISTS (
    SELECT 1 FROM user_groups, groups 
    WHERE users.id = user_groups.contact_id 
        AND groups.id = user_groups.group_id 
        AND groups.id IN (%s, %s, %s)
    )

에 대한 문서에 따르면 명시적인 정보를 사용하면 쿼리가 더 빨리 실행됩니다.join대신:

상관된 하위 쿼리를 사용하기 때문에 큰 대상 테이블과 비교할 때 조인을 사용할 때보다 성능이 거의 좋지 않습니다.

당신의 경우 다음과 같은 작업을 수행할 수 있습니다.

users = (
    session.query(ZKUser)
    .join(user_groups)
    .filter(user_groups.columns.group_id.in_([1, 2, 3]))
)

다음과 같은 SQL을 내보냅니다.

SELECT *
FROM users
JOIN user_groups ON users.id = user_groups.user_id 
WHERE user_groups.group_id IN (1, 2, 3)

사용가능in_:

session.query(ZKUser).filter(ZKGroup.id.in_([1,2])).all()

언급URL : https://stackoverflow.com/questions/6474989/sqlalchemy-filter-by-membership-in-at-least-one-many-to-many-related-table

반응형