我创建了一个具有列得分和排名的模型用户。我想定期更新用户中所有用户的排名,以便得分最高的用户排名第1,排名第二,排名第2等等。有没有在Flask-SQLAlchemy中有效实现此目的?
谢谢!
顺便说一下,这是模特:
app = Flask(__name__)
db = SQLAlchemy(app)
class User(db.Model):
id = db.Column(db.Integer, primary_key=True)
score = db.Column(db.Integer)
rank = db.Column(db.Integer)
答案 0 :(得分:4)
就人们为什么这样做而言,这样你就可以查询“排名”而无需执行聚合查询,这可能更具性能。特别是如果你想看到“用户#456的排名是什么?”没有击中每一行。
最有效的方法是单个UPDATE。使用标准SQL,我们可以使用这样的相关子查询:
UPDATE user SET rank=(SELECT count(*) FROM user AS u1 WHERE u1.score > user.score) + 1
有些数据库有像PG的UPDATE..FROM这样的扩展,我对它的经验较少,也许你可以UPDATE..FROM一个SELECT语句,它使用更高效的窗口函数立即获得排名,尽管我我不完全确定。
无论如何,我们使用SQLAlchemy的标准SQL看起来像:
from sqlalchemy.orm import aliased
from sqlalchemy import func
u1 = aliased(User)
subq = session.query(func.count(u1.id)).filter(u1.score > User.score).as_scalar()
session.query(User).update({"rank": subq + 1}, synchronize_session=False)
答案 1 :(得分:0)
只需循环使用所有用户:
users = User.query.order_by(User.score._desc()).all() #fetch them all in one query
for (rank, user) in enumerate(users):
user.rank = rank + 1 #plus 1 cause enumerate starts from zero
db.session.commit()