{"id":27953826,"url":"https://github.com/glef1x/sqla-pagination","last_synced_at":"2025-05-07T17:15:03.123Z","repository":{"id":114966101,"uuid":"468466323","full_name":"GLEF1X/sqla-pagination","owner":"GLEF1X","description":"Opinionated and powerful pagination tool for sqlalchemy","archived":false,"fork":false,"pushed_at":"2024-04-25T06:17:41.000Z","size":126,"stargazers_count":1,"open_issues_count":2,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-05-07T17:14:59.821Z","etag":null,"topics":["asyncio","keyset","keyset-pagination","keyset-paging","keysets","pagination","pagination-component","pagination-components","pagination-generator","pagination-library","sqlalchemy","sqlalchemy-orm","sqlalchemy-python"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/GLEF1X.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null}},"created_at":"2022-03-10T18:32:36.000Z","updated_at":"2023-08-17T18:02:09.000Z","dependencies_parsed_at":null,"dependency_job_id":"61df0f25-0c71-43f7-a8b2-351f1eade8bd","html_url":"https://github.com/GLEF1X/sqla-pagination","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/GLEF1X%2Fsqla-pagination","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/GLEF1X%2Fsqla-pagination/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/GLEF1X%2Fsqla-pagination/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/GLEF1X%2Fsqla-pagination/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/GLEF1X","download_url":"https://codeload.github.com/GLEF1X/sqla-pagination/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":252922318,"owners_count":21825639,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["asyncio","keyset","keyset-pagination","keyset-paging","keysets","pagination","pagination-component","pagination-components","pagination-generator","pagination-library","sqlalchemy","sqlalchemy-orm","sqlalchemy-python"],"created_at":"2025-05-07T17:15:02.492Z","updated_at":"2025-05-07T17:15:03.105Z","avatar_url":"https://github.com/GLEF1X.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cdiv\u003e\n    \u003cimg src=\"assets/sqlalchemy.png\" alt=\"sql-alchemy\" height=\"60\" /\u003e pagination for humans\n\u003c/div\u003e\n\n## Features\n\n* Support both async and sync sqlalchemy approaches without corrupting and duplicating API\n* Include variety of different pagination strategies such as `keyset(infinite scrolling)`, `limit-offset` and others\n* Support PEP 484 (typehints) and consequentially static type checking using `mypy`, `pyright` or other tool\n* Transparent page abstraction\n\n### Getting started\n\n ```python\nfrom sqlalchemy import select, create_engine\nfrom sqlalchemy.orm import sessionmaker\n\nfrom sqlapagination import LimitOffsetPaginator\n\nengine = create_engine(\"connection url\")\npool = sessionmaker(engine)\n\npaginator = LimitOffsetPaginator(select(Book).order_by(Book.id, Book.title))\n\nwith pool.begin() as session:\n    stmt = paginator.get_modified_sql_statement()\n    result = session.execute(stmt).all()\n    page = paginator.parse_result(result)\n\n    with paginator.bookmarked(page.next):\n        stmt = paginator.get_modified_sql_statement()\n        result = session.execute(stmt).all()\n        new_page = paginator.parse_result(result)\n\n```\n\n### What do bookmarks look like?\n\nBookmark is a plain dict, but for different pagination strategies\na dict's payload differ from each other\n\n#### Keyset:\n\n```python\n{\n    \"keyset_pairs\": {\n        \"id\": (1,)\n    },\n    \"direction\": \"forward\",\n}\n```\n\n#### Limit-offset:\n```python\n{\n    \"offset\": 10000,\n}\n```\n\n#### Limitations:\n\n* _Golden Rule_: Always ensure your keysets are unique per row. If you violate this condition you risk skipped rows and other nasty problems. The simplest way to do this is to always include your primary key column(s) at the end of your ordering columns.\n* Any rows containing null values in their keysets will be omitted from the results, so your ordering columns should be NOT NULL. (This is a consequence of the fact that comparisons against NULL are always false in SQL.) This may change in the future if we work out an alternative implementation; but for now we recommend using coalesce as a workaround if you need to sort by nullable columns:\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fglef1x%2Fsqla-pagination","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fglef1x%2Fsqla-pagination","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fglef1x%2Fsqla-pagination/lists"}