0

我正嘗試創建一個Flask應用程序,顯示各個玩家的最新得分。所以一個玩家可以有多個分數,但是在排行榜上,我只想顯示她最近的分數。SQLAlchemy:如果連接返回多個結果,則只顯示最新結果

我的models.py:

class Player(db.Model): 
    __tablename__ = 'player' 
    id = db.Column(db.Integer, primary_key=True) 
    firstname = db.Column(db.String, nullable=False) 
    score = db.relationship('Score', backref='player', lazy='dynamic') 

    def __init__(self, firstname): 
     self.firstname = firstname 

    def __repr__(self): 
     return '<id {}>'.format(self.id) 


class Score(db.Model): 
    __tablename__ = 'score' 
    id = db.Column(db.Integer, primary_key=True) 
    timestamp = db.Column(db.DateTime, nullable=False) 
    score = db.Column(db.String, nullable=True) 
    player_id = db.Column(db.Integer, db.ForeignKey('player.id')) 

    def __init__(self, score, player_id): 
     self.timestamp = datetime.now() 
     self.score = score 
     self.player_id = player_id 

    def __repr__(self): 
     return '<id {}>'.format(self.id) 

在我app.py我有以下幾點:

@app.route('/', methods=['GET', 'POST']) 
@login_required 
def home(): 
    """Render homepage""" 

    players_with_score = db.session.query(
     Player, Score).join(Score) 

    return render_template('home.html', players_with_score=players_with_score) 

在我(簡體)模板的Home.html:

<tbody> 
    {% for players_with_score in players_with_score %} 
    <tr> 
    <td>{{ players_with_score.Player.firstname }}</td> 
    <td>{{ players_with_score.Score.score }}</td> 
    <td>{{ players_with_score.Score.timestamp }}</td> 
    </tr> 
    {% endfor %} 
</tbody> 

這會產生一個包含所有分數的適當表格,但是現在如果玩家有多個分數,它會向該玩家顯示多次。

在查詢中我需要做什麼以確保只顯示每個玩家的最新分數?我嘗試加入.(Score.timestamp == db.session.query(func.max(Score.timestamp))),但是這樣做的唯一結果是最新的得分,而不是每個球員的最新得分。

+0

您希望[tag:most-n-per-group],答案很大程度上取決於您使用的數據庫。有一些「通用」的解決方案,例如使用外連接或標量子查詢,但也有數據庫特定的快捷方式等。 –

+0

後面的數據庫是在Heroku上運行的Postgres。 –

回答

1

您可以使用PostgreSQL中DISTINCT ON ... ORDER BY「成語」,以獲得,其中n等於1,因爲你的表是不是巨大

players_with_score = db.session.query(Player, Score).\ 
    join(Score).\ 
    distinct(Player.id).\ 
    order_by(Player.id, Score.timestamp.desc()) 

由於Score.timestamp是不是空的,你做不需要擔心降序和NULL。