问题
I'm using a framework that does pagination like this:
def get_count_query(self):
return self.session.query(func.count('*')).select_from(self.model)
def paginate(self):
... <irrelevant>...
count = self.get_count_query.scalar()
...
I want to override the get_count_query method to use my own query because I'm filtering some results and get_count_query just returns all elements in the table. Queries are created dynamically, for example one query could be:
Asset.query.join(StatusLabel).filter(StatusLabel.status == 'Deployable', or_(
Asset.assigned_to.isnot(None)),
Asset.deleted_at.is_(None))
I can count the elements in this query easily with query.count()
:
def get_count_query(self):
q = Asset.query.join(StatusLabel).filter(StatusLabel.status == 'Deployable', or_(
Asset.assigned_to.isnot(None)),
Asset.deleted_at.is_(None))
return q.count()
But this will fail once it reach the .scalar() method (and I cannot remove this method). So the question is: how can I apply func.count('*')
to an existing query?
Can I retrieve the filters from my query and apply them to the func.count('*')
query?
回答1:
you can use select_from
with join
and filter
def get_count_query(self):
return self.session.query(func.count('*')).select_from(Asset).join(StatusLabel)\
.filter(StatusLabel.status == 'Deployable', or_(
Asset.assigned_to.isnot(None),
Asset.deleted_at.is_(None)))
with subquery
def get_count_query(self):
q = Asset.query.join(StatusLabel).filter(StatusLabel.status == 'Deployable', or_(
Asset.assigned_to.isnot(None)),
Asset.deleted_at.is_(None))
return self.session.query(func.count('*')).select_from(q.subquery())
来源:https://stackoverflow.com/questions/34446725/sqlalchemy-func-count-with-filter