offset-free paging for sqlalchemy
This library implements keyset-based paging for SQLAlchemy (both ORM and core).
This library has been tested with PostgreSQL and MariaDB/MySQL. It should work with other SQLAlchemy-supported databases too provided they support row( syntax (see below).
A lot of people use SQL’s OFFSET syntax to implement paging of query results. The trouble with that is, the more pages you get through, the slower your query gets. Also, if the results you’re paging through change frequently, it’s possible to skip over or repeat results between pages. Keyset paging avoids these problems: Selecting even the millionth page is as fast as selecting the first.
sqlakeyset seems to work well so far, but is in its early stages of development, and as such, is alpha software. Treat it accordingly.
Here’s how it works with a typical ORM query:
from sqlakeyset import get_page from sqlbag import S from models import Book with S('postgresql:///books') as s: # create a session q = s.query(Book).order_by(Book.author, Book.title, Book.id) # # gets the first page page1 = get_page(q, per_page=20) # gets the key for the next page next_page = page1.paging.next # gets the second page page2 = get_page(q, per_page=20, page=next_page) # returning to the first page, getting the key previous_page = page2.paging.previous # the first page again, backwards from the previous page page1 = get_page(q, per_page=20, page=previous_page) # what if new items were added at the start? if page1.paging.has_previous: # go back even further previous_page = page1.paging.previous page1 = get_page(q, per_page=20, page=previous_page)
sqlakeyset does the following to your query in order to get the paged contents:
Paged items/rows are returned in a Page object, which is a vanilla python list, except with an attached Paging object with the paging information.
Properties such as next and previous return a 2-tuple containing the ordering key for the row, and a boolean to specify if the direction is forwards or backwards.
In our above example, the 2-tuple specifying the second page might look like:
('Joseph Heller', 'Catch 22', 123), False
The False means the query will fetch the page after the row containing Catch 22. This tuple contains two elements, title and id, to match the order by clause of the query.
The page before this row would be specified as:
('Joseph Heller', 'Catch 22', 123), True
The first and last pages are fetched with None instead of a tuple, so for the first page (this is also the default if the page parameter is not specified):
And the last page:
You will probably want to turn these keysets/bookmarks for passing around. sqlakeyset includes code to do this. To get a serialized bookmark, just add bookmark_ to the name of the property that holds the keyset you want.
Most commonly you’ll want next and previous, so:
>>> page.paging.bookmark_previous <i:1~i:2015~s:Bad Blood~i:34 >>> page.paging.bookmark_next >i:1~i:2014~s:Shake It Off~i:31
sqlakeyset uses the python csv row serializer to serialize the bookmark values (using ~ instead of a , as the separator). Direction is indicated by > (forwards/next), or < (backwards/previous) at the start of the string.
where row('a', 1) > row(name, id)
Indexing support for this syntax in MariaDB/MySQL is apparently faulty. So performance on paging large tables may be poor (Meanwhile, PostgreSQL correctly supports indexing for this syntax).
sqlakeyset is in early alpha and documentation other than this README is scarce so far. We are working on remedying this. Watch this space.
Assuming you have pip installed, all you need to do is install as follows:
$ pip install sqlakeyset
This will install sqlakeyset and also sqlalchemy if not already installed. Obviously you’ll need the necessary database driver for your chosen database to be installed also.
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
|File Name & Checksum SHA256 Checksum Help||Version||File Type||Upload Date|
|sqlakeyset-0.1.1485813522-py2.py3-none-any.whl (13.7 kB) Copy SHA256 Checksum SHA256||3.5||Wheel||Jan 30, 2017|
|sqlakeyset-0.1.1485813522.tar.gz (8.9 kB) Copy SHA256 Checksum SHA256||–||Source||Jan 30, 2017|