在Flask-SQLAlchemy中的3个表之间查询,联接和过滤?

时间:2019-10-17 12:17:49

标签: python flask sqlalchemy flask-sqlalchemy

我有3个Flask-SQLAlchemy模型(和一个关联表),具有以下关系:
比赛<->团队(多对多)
团队-> TeamPoint(一对多)

理想情况下,我想创建一个查询/联接语句,该语句将查询对决(包含2个球队),并返回与对决相同的每个球队的TeamPoint条目。我已经测试了一些纯SQL查询,并且可以通过这些JOIN 几乎获得正确的结果:

SELECT * FROM matchup m JOIN team_matchup_map tmm ON m.id=tmm.matchup_id # Joining the Matchup side JOIN team t ON tmm.team_id=t.id # Joining the Team side of the association table JOIN team_point tp ON tp.team_key=t.team_key # Joining the TeamPoint table AND m.week=2 AND tp.week=2 AND t.team_id=9 # Filtering on week and team_id

这给了我team_id = 9的团队,但没有给我其他对手。在Flask-SQLAlchemy中是否有跨多个表进行相似查询/过滤的好方法?目前,我正在2个查询中执行此操作,但这似乎并不是最有效的解决方案。以下是我的模型和查询路线:

class Team(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    team_id = db.Column(db.Integer, nullable=False)
    team_key = db.Column(db.String(30), nullable=False)
    name = db.Column(db.String(20), unique=True, nullable=False)
    league_id = db.Column(db.Integer, db.ForeignKey('league.league_id'), nullable=False)
    team_stats = db.relationship('TeamStat', backref='team', lazy=True)
    team_points = db.relationship('TeamPoint', backref='team', lazy=True)


class TeamPoint(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    week = db.Column(db.Integer, nullable=True)
    total = db.Column(db.Integer, nullable=True)
    team_key = db.Column(db.String(30), db.ForeignKey('team.team_key'))


class Matchup(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    week = db.Column(db.Integer, nullable=False)
    teams = db.relationship('Team', secondary=team_matchup_map, backref='matchup')
    stat_winners = db.relationship('StatWinner', lazy=True)

team_matchup_map = db.Table('team_matchup_map',
                           db.Column('team_id', db.ForeignKey('team.id'), primary_key=True),
                           db.Column('matchup_id', db.ForeignKey('matchup.id'), primary_key=True),
                           )

这是我当前的路线代码,其中包含2个查询:

@team.route('/matchups/<league_id>/<team_id>', methods=['GET'])
def matchups(league_id=get_user_league().league_id, team_id=get_user_team().team_id):
    week = request.args.get('week')
    # First, querying the Matchup table for the matchup involving the primary team on the given week
    # This provides both teams in the given matchup.
    matchup = Matchup.query.filter(Matchup.teams.any(league_id=league_id, team_id=team_id), Matchup.week == week).first()

    # Next, looping through each team to query the TeamPoint table for the team entry on the same week
    team_points = {}
    for mu_team in matchup.teams:
        if mu_team.team_id == team_id:
            primary_team = mu_team
            team_points[primary_team.team_key] = TeamPoint.query.filter_by(week=week, team_key=mu_team.team_key).first()            
        else:
            opponent = mu_team
            team_points[opponent.team_key] = TeamPoint.query.filter_by(week=week, team_key=mu_team.team_key).first()            

    return render_template('matchups.html', matchup=matchup, primary_team=primary_team, opponent=opponent, team_points=team_points)

0 个答案:

没有答案