0

個々のプレイヤーから最新のスコアを示すFlaskアプリケーションを作成しようとしています。プレーヤーは複数のスコアを持つことができますが、リーダーボードでは私は最新のスコアを表示したいだけです。SQLAlchemy:結合で複数の結果が返された場合の最新結果のみを表示

マイmodels.py:私のapp.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) 

私は、次のしている:

<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> 
@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で

この結果、すべてのスコアを含む適切なテーブルが得られますが、複数のスコアを持つプレイヤーには、そのプレーヤーも複数回も表示されます。

最新のスコアのみが表示されるようにするには、クエリで何をする必要がありますか?私は.(Score.timestamp == db.session.query(func.max(Score.timestamp)))を追加しようとしましたが、唯一の結果は最新のスコアであり、プレーヤー1人あたりの最新のスコアではありませんでした。あなたのテーブルが巨大ではないことを

+0

あなたは[タグ:グループごとの最大数]が必要です。使用しているDBによってその答えは大きく異なります。たとえば、外部結合やスカラーサブクエリを使用する「汎用」ソリューションがありますが、DB固有のショートカットなどもあります。 –

+0

これの背後にあるデータベースは、Herokuで動作するPostgresです。 –

答えて

1

あなたが与えられ、nが1に等しい、取得するにはPostgreSQLでDISTINCT ON ... ORDER BY「イディオム」を使用することができます。

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

Score.timestampがNULL可能でないので、あなたが降順とNULLを心配する必要はありません。

関連する問題