(필요한 경우 내가 플라스크-SQLAlchemy의를 사용하고 있습니다) 당신은 (간체) 모델을 아래와 같이 가지고 가정 :
user_to_interest = Table('user_to_interest', Base.metadata,
Column('id', Integer, primary_key=True),
Column('user_id', Integer, ForeignKey('user.id')),
Column('interest_id', Integer, ForeignKey('interest.id'))
)
event_to_interest = Table('event_to_interest', Base.metadata,
Column('id', Integer, primary_key=True),
Column('event_id', Integer, ForeignKey('event.id')),
Column('interest_id', Integer, ForeignKey('interest.id'))
)
class User(Base):
__tablename__ = 'user'
id = Column(Integer, primary_key=True)
name = Column(String)
class Event(Base):
__tablename__ = 'event'
id = Column(Integer, primary_key=True)
name = Column(String)
class Interest(Base):
__tablename__ = 'interest'
id = Column(Integer, primary_key=True)
name = Column(String)
users = relationship(User, secondary=user_to_interest, backref="interests")
events = relationship(Event, secondary=event_to_interest, backref="interests")
버전-1 : 당신이 목록에 간단한 쿼리를 할 수 있어야 생성 interest_id
들, 기본적으로 SQL
문이 당신이 원하는 :
interest_ids = [10, 144, 432]
query = session.query(Event.name)
query = query.join(event_to_interest, event_to_interest.c.event_id == Event.id)
query = query.filter(event_to_interest.c.interest_id.in_(interest_ids))
그러나 두 목록에서 관심을 더 가지고 이벤트가있는 경우, 쿼리는 샘을 반환합니다 e Event.name
여러 번. EXISTS
절을 하위 쿼리를 사용하여 다른 SQL
를 생성하는 또는, 당신은 단지 관계를 사용하여이 작업을 수행 할 수 있지만, 의미가 있어야한다 : query = session.query(Event.name.distinct())
이
버전-2 :하지만 distinct
를 사용하여 주위-작업 할 수 있습니다 동일 :
query = session.query(Event.name)
query = query.filter(Event.interests.any(Interest.id.in_(interest_ids)))
이 버전은 중복에는 문제가 없습니다.
그러나, 나는 한 단계 뒤로 이동하고 특정 사용자에 대한 interest_ids
을받을 수 있나요 가정 및 user_id
(또는 User.id
)
최종 버전 작동 쿼리를 생성 할 것입니다 : 두 번 any
을 사용하여 :
def get_events_for_user(user_id):
#query = session.query(Event.name)
query = session.query(Event) # @note: I assume name is not enough
query = query.filter(Event.interests.any(Interest.users.any(User.id == user_id)))
return query.all()
하나는이 그리 아름다운 SQL 문을 생성하는 agrue 수 있지만, 이것은 정확하게 구현 세부 사항을 숨 깁니다 SQLAlchemy의 사용의 아름다움이다.
보너스 : 더 많은 중복 관심을 가지고 이벤트에 더 높은 우선 순위를 부여 할 사실 수 있습니다. 이 경우에 도움이 될 수 있습니다 :
query = session.query(Event, func.count('*').label("num_interests"))
query = query.join(Interest, Event.interests)
query = query.join(User, Interest.users)
query = query.filter(User.id == user_id)
query = query.group_by(Event)
# first order by overlaping interests, then also by event.date
query = query.order_by(func.count('*').label("num_interests").desc())
#query = query.order_by(Event.date)
'WHERE' 절이'event_to_interest.interest_id'가 아닌'event_to_interest.id'를 확인하고 있습니까? – van
@van, 맞아. 'interest_id'가 있어야합니다. –