Peewee
fastapi_pagination.ext.peewee.paginate allows you to paginate peewee queries.
It can work for both sync and async peewee databases.
Note
Async pagination (apaginate) requires peewee >= 4.0.0 with playhouse.pwasyncio and greenlet.
Install with: uv pip install fastapi-pagination[peewee].
See Peewee Async Documentation for more details.
Note
Cursor pagination is not currently supported, as it is only available via the Playhouse Postgresql extension.
Example: FastAPI¶
from contextlib import asynccontextmanager
from fastapi import FastAPI, Depends
from pydantic import BaseModel
from peewee import Model, TextField, IntegerField, SqliteDatabase
from fastapi_pagination import Page, Params, set_page
from fastapi_pagination.ext.peewee import paginate
db = SqliteDatabase("example.db")
class User(BaseModel):
name: str
age: int
class UserModel(Model):
name = TextField()
age = IntegerField()
class Meta:
database = db
@asynccontextmanager
async def lifespan(app: FastAPI):
db.create_tables([UserModel])
for name, age in [("John", 25), ("Jane", 30), ("Bob", 20)]:
UserModel.get_or_create(name=name, age=age)
yield
app = FastAPI(lifespan=lifespan)
@app.get("/users", response_model=Page[User])
async def get_users(params: Params = Depends()):
set_page(Page[User])
return paginate(UserModel.select(), params)
Details¶
paginate accepts the following peewee related arguments:
db- Database instance. Required for raw SQL queries, optional otherwise (extracted from query's model).query- is the query that you want to paginate, it can be either a Peewee query or a raw SQL string.prefetch- A tuple of queries for eager loading related records (avoids N+1 query problems).
Sync Usage¶
from peewee import Model, TextField, IntegerField, SqliteDatabase
from fastapi_pagination import set_params, set_page, Page, Params
from fastapi_pagination.ext.peewee import paginate
db = SqliteDatabase(":memory:")
class User(Model):
name = TextField()
age = IntegerField()
class Meta:
database = db
db.create_tables([User])
for name, age in [("John", 25), ("Jane", 30), ("Bob", 20)]:
User.create(name=name, age=age)
set_page(Page[User])
set_params(Params(page=1, size=10))
page = paginate(User.select().order_by(User.id))
print(page)
Async Usage¶
from peewee import Model, TextField, IntegerField
from playhouse.pwasyncio import AsyncSqliteDatabase, greenlet_spawn
from fastapi_pagination import set_params, set_page, Page, Params
from fastapi_pagination.ext.peewee import apaginate
db = AsyncSqliteDatabase(":memory:")
class User(Model):
name = TextField()
age = IntegerField()
class Meta:
database = db
async def get_users():
await greenlet_spawn(db.create_tables, [User])
for name, age in [("John", 25), ("Jane", 30), ("Bob", 20)]:
await greenlet_spawn(User.create, name=name, age=age)
set_page(Page[User])
set_params(Params(page=1, size=10))
page = await apaginate(User.select().order_by(User.id))
print(page)
Prefetch Usage¶
from peewee import Model, TextField, IntegerField, ForeignKeyField
from fastapi_pagination import set_params, set_page, Page, Params
from fastapi_pagination.ext.peewee import paginate
db = SqliteDatabase(":memory:")
class User(Model):
name = TextField()
class Meta:
database = db
class Order(Model):
user = ForeignKeyField(User, backref="orders")
name = TextField()
class Meta:
database = db
db.create_tables([User, Order])
set_page(Page[User])
set_params(Params(page=1, size=10))
page = paginate(User.select(), prefetch=(Order.select(),))
for user in page.items:
print(user.name, [order.name for order in user.orders])