New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Version 0.5.0 plan #25
Comments
Hi @greyli. In case you'd be tempted to get inspiration from flask-smorest for the pagination feature, you may want to have a look at this thread which details an issue I'm facing with its current implementation: sqlalchemy/sqlalchemy#6333. The feature worked with the DB ORM/ODM we were using by the time, but we might have made abusive assumptions and now the chickens come home to roost. |
Thank you for the info @lafrech. Adding pagination support seems a bit tricky. I will try to find an ideal solution, otherwise, we may just leave this to the user and provide a thorough guide in the documentation (It's the feature strategy of this project). For now, without the built-in pagination support, the user can achieve pagination with the following steps: Building a schema with the nested schema and a pagination schemaclass PaginationSchema(Schema):
pages = Integer()
per_page = Integer()
page = Integer()
next = URL()
prev = URL()
first = URL()
last = URL()
current = URL()
total = Integer()
class PetSchema(Schema):
id = Integer()
name = String()
category = String()
class PetsSchema(Schema):
pets = List(ma.Nested(PetSchema))
pagination = Nested(PaginationSchema) Writing a function to build pagination datadef build_pagination_schema(endpoint, pagination, **kwargs):
per_page = pagination.per_page
def get_page_url(page):
return url_for(
endpoint,
page=page,
per_page=per_page,
_external=True,
**kwargs
)
next = get_page_url(pagination.next_num) if pagination.has_next else ''
prev = get_page_url(pagination.prev_num) if pagination.has_prev else ''
return {
'total': pagination.total,
'pages': pagination.pages,
'per_page': per_page,
'page': pagination.page,
'next': next,
'prev': prev,
'first': get_page_url(1),
'last': get_page_url(pagination.pages),
'current': get_page_url(pagination.page),
} Return the object list and the pagination object in the view functionThen return both the items and the pagination object in the view function (assuming use Flask-SQLAlchemy): class PaginationQuerySchema(Schema):
page = Integer(missing=1)
per_page = Integer(missing=20)
@app.get('/pets')
@input(PaginationQuerySchema, 'query')
@output(PetsSchema)
def get_pets(query):
pagination = Pet.query.paginate(query['page'], query['per_page'])
pets = pagination.items
return {
'pets': pets,
'pagination': build_pagination_schema('get_pets', pagination)
} |
Moved pagination to 0.6.0 plan. |
The situation is not as bad as I first thought. Being unfamiliar with the internals, I found the linked conversation very instructive. But ultimately, the pagination feature in flask-smorest is not broken. It just uses a feature that is being un-recommended in SQLALchemy that uses offsets for pagination. The same feature Flask-SQLAlchemy uses, I suppose (didn't check but pretty sure cause "what else ?"). An automatic feature can't do better than this. flask-smorest also aims at providing all it can without making too many assumptions and without blocking other use cases. It offers two modes:
The feature is of course optional. Almost but not exactly independent: to achieve auto-doc, it needs to know which response (which status code) is the one that gets the pagination (which is the "normal path", as opposed to error paths). This is possible because the Depending on the object return by the data source driver, the paginator class can be more or less challenging to achieve. The example we provide happens to work with pymongo (<4) and SQLAlchemy (1.0 API but not removed in 2.0) but it is not as generic as I hoped. Nothing really new. |
Version 0.5.0 released. |
Next: Version 0.6.0 plan
The text was updated successfully, but these errors were encountered: