Reputation: 122
I have a table which stores some movie info and a score.
I want to be able to know what position a movie has after being ordered by that score (ie 'The Shining' has the 10th highest score) but it would obvisouly not necessarily be in the tenth place of the database or have the id 10.
Would it be possible to get something like this, either through a query or somehow keeping it as a value in the table?
Thank you!
The table looks like this:
class MoviePersonScores(db.Model):
movie_id = db.Column(db.Integer, db.ForeignKey('movie.id'), primary_key=True)
person_id = db.Column(db.Integer, db.ForeignKey('person.id'), primary_key=True)
score = db.Column(db.Integer)
person = relationship("Person", back_populates="movies")
movie = relationship("Movie", back_populates="people")
Upvotes: 1
Views: 610
Reputation: 12038
This query can be broken down into two distinct steps:
Because rank
is relative to the entire collection of your table, you'll have no choice but to calculate the rank for every record. However, the magic of sqlalchemy
allows you to leverage the database to execute those calculations.
Second, your application doesn't need the rank of every object. So we'll chain the query to only provide the one we'd like.
More sqlalchemy
magic, we can chain these queries to execute in a single database transaction:
from sqlalchemy import func
# Assuming you have a session established somewhere
# though `MoviePersonScores.query` may work just the same
query = session.query(
MoviePersonScores,
func.rank()\
.over(
order_by=MoviePersonScores.score
)\
.label('rank')
)
# now filter
query = query.filter_by(movie_id=movie_id)
# now execute:
my_movie = query.all()
# Or, just get the first value
my_movie = query.first()
Upvotes: 2