Created
October 23, 2017 12:30
-
-
Save gaganpreet/9a997b13bd38740b9a29b43578ce457b to your computer and use it in GitHub Desktop.
Flask SQLAlchemy Pagination without count query
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
def optimised_pagination(query, per_page, page): | |
'''A more efficient pagination for SQLAlchemy | |
Fetch one item before offset (to know if there's a previous page) | |
Fetch one item after limit (to know if there's a next page) | |
The trade-off is that the total items are not available, but if you don't need them | |
there's no need for an extra COUNT query | |
''' | |
offset_start = (page - 1) * per_page | |
query_offset = max(offset_start - 1, 0) | |
optimistic_items = query.limit(per_page + 1).offset(query_offset).all() | |
if page == 1: | |
if len(optimistic_items) == per_page + 1: | |
# On first page, there's no optimistic item for previous page | |
items = optimistic_items[:-1] | |
else: | |
# The number of items on the first page is fewer than per_page | |
items = optimistic_items | |
elif len(optimistic_items) == per_page + 2: | |
# We fetched an extra item on both ends | |
items = optimistic_items[1:-1] | |
else: | |
# An extra item only on the head | |
# This is the last page | |
items = optimistic_items[1:] | |
# This total is at least the number of items for the query, could be more | |
total = offset_start + len(optimistic_items) | |
return Pagination(query, page, per_page, total, items) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment