定义查询模型时使用的表达式

时间:2018-08-11 21:26:02

标签: python python-3.x flask sqlalchemy flask-sqlalchemy

我正在尝试通过递减计算游戏和订单的平均评分。 在我的models.py中,我定义了一个混合属性

class Review(db.Model):
  id = db.Column(db.Integer, primary_key=True)
  rating = db.Column(db.Numeric(precision=2, scale=1), index=True)
  body = db.Column(db.String(140))
  user_id = db.Column(db.Integer, db.ForeignKey('user.id'))
  game_id = db.Column(db.Integer, db.ForeignKey('game.id'))

class Game(db.Model):
  id = db.Column(db.Integer, primary_key=True)
  title = db.Column(db.String(255), index=True, unique=True)
  reviews = db.relationship('Review', backref='game', lazy='dynamic')

  @hybrid_property
  def avg_rating(self):
    total_rating = 0
    reviews = Review.query.filter_by(game_id=self.id).all()
    for review in reviews:
      total_rating += review.rating

    return total_rating / len(reviews)

但是当我尝试在我的路线中查询平均评分时。py

games = Game.query.order_by(Game.avg_rating.desc())

我收到此错误

AttributeError: 'decimal.Decimal' object has no attribute 'desc'

我可能需要在我的models.py中执行类似的操作,但是如何?

@avg_rating.expression
def avg_rating(cls):
  # what to write here

1 个答案:

答案 0 :(得分:0)

您想要做的事情在sqlalchemy文档中描述为Correlated Subquery Relationship Hybrid

这是纯SqlAlchemy版本:

import sqlalchemy as sa

@avg_rating.expression
def avg_rating(cls):
    return sa.select([sa.func.avg(Review.rating)]).where(Review.game_id == cls.id).label('avg_rating')

flask-sqlalchemy版本应如下所示(但我在这里没有,所以不能100%确定):

@avg_rating.expression
def avg_rating(cls):
    return db.select([db.func.avg(Review.rating)]).where(Review.game_id == cls.id).label('avg_rating')