Flask Sqlalchemy - 使用多个值查询多对多
Flask Sqlalchemy - query many to many with several values
我在比赛和球队之间有一个多对多的关系,一场比赛可以有多个球队参加,每个球队可以有不止一场比赛。模型是:
class Match(db.Model):
__tablename__ = 'match'
id = Column(
db.Integer,
primary_key=True,
autoincrement=True)
teams = db.relationship('Team', secondary='team_match_link')
class Team(db.Model):
__tablename__ = 'team'
id = Column(
db.Integer,
primary_key=True,
autoincrement=True)
matches = db.relationship('Match', secondary='team_match_link')
class TeamMatchLink(db.Model):
__tablename__ = 'team_match_link'
match_id = Column(
db.Integer,
db.ForeignKey('match.id'),
primary_key=True
)
team_id = Column(
db.Integer,
db.ForeignKey('team.id'),
primary_key=True
)
给定两支球队 [T1, T2]
,我如何查询完全包含这两支球队而没有其他球队的比赛?
这给了我至少包含两支球队的比赛,然后我当然可以检查这些比赛中是否还有其他球队。但它看起来很难看,我确定有 better/more 有效的方法?理想情况下,该解决方案应该适用于 n
个团队,而不会让我陷入困境。
res1 = match.query.filter(match.team.any(id=T1.id)).all()
res2 = match.query.filter(match.team.any(id=T2.id)).all()
res = [i for i in res1 if i in res2]
查询比赛队伍 links 并通过统计条目数进行聚合。
下面的查询和一些解释:
your_teams = [T1.id, T2.id]
result = db.session.query(Match, TeamMatchLink).filter(TeamMatchLink.team_id.in_(your_teams)).group_by(TeamMatchLink.match_id).having(func.count(TeamMatchLink.team_id) == len(your_teams)).join(Match).all()
查询由几个部分和想法串在一起:
team_link_query = db.session.query(TeamMatchLink).filter(TeamMatchLink.team_id.in_(your_teams)))
这将选择包含您想要的团队的所有团队 link。
applicable_matches_query = team_link_query.group_by(TeamMatchLink.match_id).having(func.count(TeamMatchLink.team_id) == len(your_teams))
这会聚合团队匹配 link 以查找包含您需要的所有团队的匹配。 (一场比赛将出现 nr 次,球队 link 将与 your_teams
列表匹配)
最后,加入将为您匹配。您当然可以减少查询,只为您直接提供来自团队比赛 link table 的比赛 ID。
我在比赛和球队之间有一个多对多的关系,一场比赛可以有多个球队参加,每个球队可以有不止一场比赛。模型是:
class Match(db.Model):
__tablename__ = 'match'
id = Column(
db.Integer,
primary_key=True,
autoincrement=True)
teams = db.relationship('Team', secondary='team_match_link')
class Team(db.Model):
__tablename__ = 'team'
id = Column(
db.Integer,
primary_key=True,
autoincrement=True)
matches = db.relationship('Match', secondary='team_match_link')
class TeamMatchLink(db.Model):
__tablename__ = 'team_match_link'
match_id = Column(
db.Integer,
db.ForeignKey('match.id'),
primary_key=True
)
team_id = Column(
db.Integer,
db.ForeignKey('team.id'),
primary_key=True
)
给定两支球队 [T1, T2]
,我如何查询完全包含这两支球队而没有其他球队的比赛?
这给了我至少包含两支球队的比赛,然后我当然可以检查这些比赛中是否还有其他球队。但它看起来很难看,我确定有 better/more 有效的方法?理想情况下,该解决方案应该适用于 n
个团队,而不会让我陷入困境。
res1 = match.query.filter(match.team.any(id=T1.id)).all()
res2 = match.query.filter(match.team.any(id=T2.id)).all()
res = [i for i in res1 if i in res2]
查询比赛队伍 links 并通过统计条目数进行聚合。
下面的查询和一些解释:
your_teams = [T1.id, T2.id]
result = db.session.query(Match, TeamMatchLink).filter(TeamMatchLink.team_id.in_(your_teams)).group_by(TeamMatchLink.match_id).having(func.count(TeamMatchLink.team_id) == len(your_teams)).join(Match).all()
查询由几个部分和想法串在一起:
team_link_query = db.session.query(TeamMatchLink).filter(TeamMatchLink.team_id.in_(your_teams)))
这将选择包含您想要的团队的所有团队 link。
applicable_matches_query = team_link_query.group_by(TeamMatchLink.match_id).having(func.count(TeamMatchLink.team_id) == len(your_teams))
这会聚合团队匹配 link 以查找包含您需要的所有团队的匹配。 (一场比赛将出现 nr 次,球队 link 将与 your_teams
列表匹配)
最后,加入将为您匹配。您当然可以减少查询,只为您直接提供来自团队比赛 link table 的比赛 ID。