Cobble
Cobble

Reputation: 122

SQLAlchemy get position when ordered by value?

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

Answers (1)

Yaakov Bressler
Yaakov Bressler

Reputation: 12038

This query can be broken down into two distinct steps:

  1. get the rank of each record in your table
  2. get the rank for a specific record

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

Related Questions