No project description provided
Project description
sqlalchemy-relay-pagination
Python package that make setting up relay-style pagination with SQLAlchemy easy.
Quickstart
Installation
uv add sqlalchemy-relay-pagination
Schema
Define your connection types in SDL:
type Query {
users(first: Int, last: Int, after: String, before: String): UserConnection!
}
type UserConnection {
edges: [UserEdge!]!
pageInfo: PageInfo!
}
type UserEdge {
node: User!
cursor: String!
}
type PageInfo {
hasNextPage: Boolean!
hasPreviousPage: Boolean!
startCursor: String
endCursor: String
totalCount: Int
}
type User {
id: Int!
name: String!
posts(first: Int, last: Int, after: String, before: String): PostConnection!
}
type PostConnection {
edges: [PostEdge!]!
pageInfo: PageInfo!
}
type PostEdge {
node: Post!
cursor: String!
}
type Post {
id: Int!
title: String!
}
Resolver
from ariadne import QueryType
from sqlalchemy import select
from sqlalchemy_relay_pagination import paginate
from sqlalchemy_relay_pagination.graphql import extract_requested_fields
query_type = QueryType()
@query_type.field("users")
async def resolve_users(_, info, first=None, last=None, after=None, before=None):
session = info.context["session"]
return await paginate(
session,
select(User),
order_by=User.id,
first=first,
last=last,
after=after,
before=before,
requested_fields=extract_requested_fields(info),
)
extract_requested_fields inspects the GraphQL selection set and tells paginate
which fields the client actually requested — skipping the COUNT(*) query when
totalCount is absent, and skipping the extra-row fetch when neither hasNextPage
nor hasPreviousPage is selected.
Batch-loading nested connections (avoiding N+1)
For nested paginated fields (e.g. User.posts), use paginate_many inside a
dataloader to fetch all parents' children in a single query:
from aiodataloader import DataLoader
from ariadne import ObjectType
from sqlalchemy_relay_pagination import paginate_many
user_type = ObjectType("User")
class UserPostsLoader(DataLoader):
def __init__(self, session, first, last, fields):
super().__init__()
self._session = session
self._first = first
self._last = last
self._fields = fields
async def batch_load_fn(self, user_ids):
results = await paginate_many(
self._session,
select(Post),
model=Post,
partition_by=Post.user_id,
order_by=Post.id,
keys=list(user_ids),
first=self._first,
last=self._last,
requested_fields=self._fields,
)
return [results[uid] for uid in user_ids]
@user_type.field("posts")
async def resolve_user_posts(user, info, first=None, last=None):
session = info.context["session"]
loaders = info.context["loaders"]
loader_key = (first, last)
if loader_key not in loaders:
loaders[loader_key] = UserPostsLoader(
session, first, last, extract_requested_fields(info)
)
return await loaders[loader_key].load(user.id)
Note: when
afterorbeforecursors are provided,paginate_manyfalls back to one query per parent key instead of a single batched query, because each parent may be at a different cursor position. Results are still correct; only the single-query optimisation is lost.
Global configuration
Call configure() once at application startup:
from sqlalchemy_relay_pagination import configure, PaginationConfig
configure(PaginationConfig(default_page_size=20, max_page_size=100))
Settings can also be provided via environment variables:
SQLALCHEMY_RELAY_PAGINATION_DEFAULT_PAGE_SIZE=20
SQLALCHEMY_RELAY_PAGINATION_MAX_PAGE_SIZE=100
Resources
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file sqlalchemy_relay_pagination-0.1.0rc2.tar.gz.
File metadata
- Download URL: sqlalchemy_relay_pagination-0.1.0rc2.tar.gz
- Upload date:
- Size: 99.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
1a68dc51f833c5d3f39be84e89a6dbbb3911ad9bc539d77f869c7044fb77b980
|
|
| MD5 |
d77d85c1e59792378083f0fbc4b3ca4c
|
|
| BLAKE2b-256 |
410cb64fb3558ab0c1b76018a0cfb636a31478898c0205bd86d2768262819f70
|
Provenance
The following attestation bundles were made for sqlalchemy_relay_pagination-0.1.0rc2.tar.gz:
Publisher:
publish-package.yaml on fedirz/sqlalchemy-relay-pagination
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
sqlalchemy_relay_pagination-0.1.0rc2.tar.gz -
Subject digest:
1a68dc51f833c5d3f39be84e89a6dbbb3911ad9bc539d77f869c7044fb77b980 - Sigstore transparency entry: 1154575208
- Sigstore integration time:
-
Permalink:
fedirz/sqlalchemy-relay-pagination@868f1ca8a885e5e9fedbc1d240e7b9a3417f198b -
Branch / Tag:
refs/heads/master - Owner: https://github.com/fedirz
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish-package.yaml@868f1ca8a885e5e9fedbc1d240e7b9a3417f198b -
Trigger Event:
workflow_dispatch
-
Statement type:
File details
Details for the file sqlalchemy_relay_pagination-0.1.0rc2-py3-none-any.whl.
File metadata
- Download URL: sqlalchemy_relay_pagination-0.1.0rc2-py3-none-any.whl
- Upload date:
- Size: 19.5 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
3f92677aff68d63b785a97e6d8df0e47c02dd774baf72e921f683774a0af1b79
|
|
| MD5 |
e7bd89fc0ffa5d4a91293f7529931577
|
|
| BLAKE2b-256 |
0bbc0eafef5ab1a8c49031c9c3598ccad01953d9b3593f1b7ee85e268babda6d
|
Provenance
The following attestation bundles were made for sqlalchemy_relay_pagination-0.1.0rc2-py3-none-any.whl:
Publisher:
publish-package.yaml on fedirz/sqlalchemy-relay-pagination
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
sqlalchemy_relay_pagination-0.1.0rc2-py3-none-any.whl -
Subject digest:
3f92677aff68d63b785a97e6d8df0e47c02dd774baf72e921f683774a0af1b79 - Sigstore transparency entry: 1154575209
- Sigstore integration time:
-
Permalink:
fedirz/sqlalchemy-relay-pagination@868f1ca8a885e5e9fedbc1d240e7b9a3417f198b -
Branch / Tag:
refs/heads/master - Owner: https://github.com/fedirz
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish-package.yaml@868f1ca8a885e5e9fedbc1d240e7b9a3417f198b -
Trigger Event:
workflow_dispatch
-
Statement type: