How to paginate MongoEngine records in your Python 3 Flask application
Flask and MongoEngine help makes development work easier.
One common task in the development of backend applications is the pagination of database records. Without pagination, the application server can run out of memory while generating a response from the database records.
This post discusses a way to paginate MongoEngine records in your Python 3 Flask application using the facilities provided by the Flask-MongoEngine extension.
Installing flask-mongoengine to your Python 3 environment
pip install flask-mongoengine
Associating an instance of flask_mongoengine.MongoEngine
with an instance of Flask
Once our Python 3 environment had included flask-mongoengine, we can proceed to associate an instance of flask_mongoengine.MongoEngine
with an instance of Flask
in our Python 3 script.
To do so, we can use either the following set of codes:
from flask import Flask from flask_mongoengine import MongoEngine app = Flask(__name__) app.config.from_pyfile('the-config.cfg') db = MongoEngine(app)
or the following set of codes:
from flask import Flask from flask_mongoengine import MongoEngine app = Flask(__name__) app.config.from_pyfile('the-config.cfg') db = MongoEngine() # Init app later db.init_app(app)
Defining a subclass of flask_mongoengine.Document
to represent our MongoDB collection
The next set of codes that we need to write is the definition of a subclass of flask_mongoengine.Document
that will represent our MongoDB collection:
# Note: the db variable refers to the flask_mongoengine.MongoEngine # instance that we had created earlier. class Friend(db.Document): name = db.StringField(max_length=50, required=True) phone_number = db.StringField(max_length=50, required=True)
Note that we had used the db
variable that we can created earlier to get a reference to the flask_mongoengine.Document
class. We had also defined the fields that we expect the documents in our MongoDB collection to have.
Calling the paginate function from flask_mongoengine.BaseQuerySet
Once we had defined a subclass of flask_mongoengine.Document
, we can then use the following codes to query our MongoDB collection and get a paginated record of the result:
friends_pagination = Friend.objects.paginate(page=1, per_page=10) # Get information of current pagination session current_page = friends_pagination.page total_pages_for_query = friends_pagination.pages item_per_page = friends_pagination.per_page total_number_of_items_that_match_query = friends_pagination.total list_of_items = friends_pagination.items
We first define the page number and items per page via the page
and per_page
input parameters of the flask_mongoengine.BaseQuerySet.paginate
function. The execution of this function will return an instance of flask_mongoengine.pagination.Pagination
class that represents a particular page of a MongoDB query that we had indicated.
We can then use the instance of flask_mongoengine.pagination.Pagination
to retrieve:
- the current page number via the
page
attribute. - the total number of pages for the MongoDB query via the
pages
attribute. - the number of items per page via the
per_page
attribute. - the total number of items that are returned for the MongoDB query via the
total
attribute. - the list of items in the current page via the
items
attribute.
AttributeError: 'QuerySet' object has no attribute 'paginate'?
The paginate
function is provided by the BaseQuerySet
class inside the flask_mongoengine
package which builds on the mongoengine
package.
Therefore, there can be a chance where we accidentally define our MongoDB collection representation class with the Document class from the mongoengine package instead of the Document
class from the flask_mongoengine
package:
import mongoengine as db class Friend(db.Document): name = db.StringField(max_length=50, required=True) phone_number = db.StringField(max_length=50, required=True)
Doing so will result in the call to Friend.objects
to return an instance of mongoengine.QuerySet
instead. This is why the AttributeError
is thrown when we try to call the paginate
function.