Skip to content

Instantly share code, notes, and snippets.

@stuartaccent
Created March 3, 2023 23:50
Show Gist options
  • Save stuartaccent/9cb200ca575df9abe0a4381d18d2cd01 to your computer and use it in GitHub Desktop.
Save stuartaccent/9cb200ca575df9abe0a4381d18d2cd01 to your computer and use it in GitHub Desktop.
Fastapi, Pydantic, Sqlalchemy List filter, order, limit model
from typing import List, Optional
from accentdatabase.session import get_session
from fastapi import Depends, Query
from pydantic import BaseModel, Field
from sqlalchemy import func, or_, select
from sqlalchemy.ext.asyncio import AsyncSession
from models import Model
class ListFilter(BaseModel):
"""
usage:
?search=foo
?search=foo&search=bar
?limit=100
?search=foo&limit=100
ordering is by the searched fields in order for simplicity only
"""
limit: int = 200
search: Optional[List[str]] = Field(Query([]))
@property
def search_regex(self):
q = "".join(map(lambda s: f"(?=.*{s})", self.search))
return f"{q}.*"
def prepare(self, statement, *search_field):
if len(self.search) > 0:
terms = map(lambda f: f.op("~*")(self.search_regex), search_field)
statement = statement.filter(or_(*terms))
return statement.limit(self.limit).order_by(*search_field)
@router.get("", response_model=List[ModelRead])
async def get_items(
filters: ListFilter = Depends(),
session: AsyncSession = Depends(get_session),
):
qs = filters.prepare(select(Model), Model.name, Model.title)
return list(await session.scalars(qs))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment