Created
March 3, 2023 23:50
-
-
Save stuartaccent/9cb200ca575df9abe0a4381d18d2cd01 to your computer and use it in GitHub Desktop.
Fastapi, Pydantic, Sqlalchemy List filter, order, limit model
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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