pgorsira
pgorsira

Reputation: 202

SQLAlchemy order by hybrid property that references relationship

My SQLAlchemy models:

class Cover(db.Model):
    # ... a bunch of other fields ...

    @hybrid_property
    def number_of_requests(self):
        if self.requests:
            return len(self.requests)
        return 0

    @number_of_requests.expression
    def number_of_requests(cls):
        return func.count(cls.requests)

class Request(db.Model):
    # ... a bunch of other fields ...

    # Cover that this request is requesting
    cover_id = db.Column(db.Integer, db.ForeignKey('cover.id')
    cover = db.relationship('Cover',
                        backref=backref("requests", cascade="all, delete-orphan"))

So, a simple one-to-many relationship between Cover and Request. The number_of_requests hybrid property should return the number of Requests associated with that particular Cover.

Now, in one of my Flask routes, I'm trying to grab the top 5 Covers by number of Requests. Here's what that looks like now:

# Get top cover requests
covers = Cover.query.order_by(Cover.number_of_requests).limit(5).all()

Unfortunately, this gives

ProgrammingError: (ProgrammingError) missing FROM-clause entry for table "request"

I suspect this is because in number_of_requests(cls) I'm trying to count the size of the requests list but SQLAlchemy hasn't included the request table in the original query. Any ideas on how to do that to avoid getting this error?

Upvotes: 3

Views: 7815

Answers (1)

van
van

Reputation: 76992

Change your expression part to:

@number_of_requests.expression
def number_of_requests(cls):
    return (select([func.count(Request.id)])
            .where(Request.cover_id == cls.id))

and read Correlated Subquery Relationship Hybrid again.

Upvotes: 6

Related Questions