Reputation: 4426
I am using sqlalchemy to retrieve a list of objects using the paginate function
results = models.Object.query.filter(models.Object.id.in_(list_of_ids)).paginate(page, 10, False)
Sometimes list_of_ids
can be empty. I noticed that queries where this list is empty are very slow. There is also a warning telling me that querying empty lists can be slow. However, to keep my functionality simple I need an empty paginate object. Is there a way to get that without running a query?
Upvotes: 1
Views: 1320
Reputation: 87084
You could probably mess around and instantiate your own instance of an empty Pagination
object in order to avoid a query, but it might just be easier to perform a simple, fast, query that returns no rows:
>>> empty_paginator = models.Object.query.filter_by(id=None).paginate()
>>> empty_paginator.items
[]
>>> empty_paginator.has_next
False
The query should be very fast as it is on the table's primary key and will therefore use an index. Just make sure that you select something that doesn't exist, e.g. an id of None
. Then use it like this:
if list_of_ids:
results = models.Object.query.filter(models.Object.id.in_(list_of_ids)).paginate(page, 10, False)
else:
results = models.Object.query.filter_by(id=-1).paginate()
Another way would be to subclass a Pagination
object, overriding the methods that require a valid query object in order to avoid making a query:
class EmptyPaginator(flask.ext.sqlalchemy.Pagination):
def __init__(self):
super(EmptyPaginator, self).__init__(None, 1, 1, 0, [])
def next(self, error_out=False):
self.page += 1
return self
def prev(self, error_out=False):
self.page -= 1
return self
Use it like this:
if list_of_ids:
results = models.Object.query.filter(models.Object.id.in_(list_of_ids)).paginate(page, 10, False)
else:
results = EmptyPaginator()
or this (more succinct but less readable):
results = models.Object.query.filter(models.Object.id.in_(list_of_ids)).paginate(page, 10, False) if list_of_ids else EmptyPaginator()
Upvotes: 1