mirror of
https://github.com/mealie-recipes/mealie.git
synced 2025-05-24 01:12:54 -04:00
fix performance issues on /api/foods (#2163)
* fix performance issues on /api/foods * fix comment * actually apply query-options
This commit is contained in:
parent
666085b9ca
commit
9d35b0923a
@ -1,5 +1,7 @@
|
||||
from pydantic import UUID4
|
||||
from sqlalchemy import select
|
||||
from sqlalchemy.orm import joinedload
|
||||
from sqlalchemy.orm.interfaces import LoaderOption
|
||||
|
||||
from mealie.db.models.recipe.ingredient import IngredientFoodModel
|
||||
from mealie.schema.recipe.recipe_ingredient import IngredientFood
|
||||
@ -29,3 +31,9 @@ class RepositoryFood(RepositoryGeneric[IngredientFood, IngredientFoodModel]):
|
||||
|
||||
def by_group(self, group_id: UUID4) -> "RepositoryFood":
|
||||
return super().by_group(group_id)
|
||||
|
||||
def paging_query_options(self) -> list[LoaderOption]:
|
||||
return [
|
||||
joinedload(IngredientFoodModel.extras),
|
||||
joinedload(IngredientFoodModel.label),
|
||||
]
|
||||
|
@ -7,6 +7,7 @@ from typing import Any, Generic, TypeVar
|
||||
from fastapi import HTTPException
|
||||
from pydantic import UUID4, BaseModel
|
||||
from sqlalchemy import Select, delete, func, select
|
||||
from sqlalchemy.orm.interfaces import LoaderOption
|
||||
from sqlalchemy.orm.session import Session
|
||||
from sqlalchemy.sql import sqltypes
|
||||
|
||||
@ -284,6 +285,10 @@ class RepositoryGeneric(Generic[Schema, Model]):
|
||||
q = self._query().filter(attribute_name == attr_match)
|
||||
return [eff_schema.from_orm(x) for x in self.session.execute(q).scalars().all()]
|
||||
|
||||
def paging_query_options(self) -> list[LoaderOption]:
|
||||
# Override this in subclasses to specify joinedloads or similar for page_all
|
||||
return []
|
||||
|
||||
def page_all(self, pagination: PaginationQuery, override=None) -> PaginationBase[Schema]:
|
||||
"""
|
||||
pagination is a method to interact with the filtered database table and return a paginated result
|
||||
@ -296,19 +301,18 @@ class RepositoryGeneric(Generic[Schema, Model]):
|
||||
"""
|
||||
eff_schema = override or self.schema
|
||||
|
||||
q = self._query()
|
||||
q = self._query().options(*self.paging_query_options())
|
||||
|
||||
fltr = self._filter_builder()
|
||||
q = q.filter_by(**fltr)
|
||||
q, count, total_pages = self.add_pagination_to_query(q, pagination)
|
||||
|
||||
try:
|
||||
data = self.session.execute(q).scalars().all()
|
||||
data = self.session.execute(q).unique().scalars().all()
|
||||
except Exception as e:
|
||||
self._log_exception(e)
|
||||
self.session.rollback()
|
||||
raise e
|
||||
|
||||
return PaginationBase(
|
||||
page=pagination.page,
|
||||
per_page=pagination.per_page,
|
||||
|
@ -2,12 +2,12 @@ from __future__ import annotations
|
||||
|
||||
import datetime
|
||||
import enum
|
||||
from typing import Any
|
||||
from uuid import UUID, uuid4
|
||||
|
||||
from pydantic import UUID4, Field, validator
|
||||
from pydantic.utils import GetterDict
|
||||
|
||||
from mealie.db.models.recipe.ingredient import IngredientFoodModel
|
||||
from mealie.schema._mealie import MealieModel
|
||||
from mealie.schema._mealie.types import NoneFloat
|
||||
from mealie.schema.response.pagination import PaginationBase
|
||||
@ -37,14 +37,19 @@ class IngredientFood(CreateIngredientFood):
|
||||
update_at: datetime.datetime | None
|
||||
|
||||
class Config:
|
||||
orm_mode = True
|
||||
class _FoodGetter(GetterDict):
|
||||
def get(self, key: Any, default: Any = None) -> Any:
|
||||
# Transform extras into key-value dict
|
||||
if key == "extras":
|
||||
value = super().get(key, default)
|
||||
return {x.key_name: x.value for x in value}
|
||||
|
||||
@classmethod
|
||||
def getter_dict(cls, name_orm: IngredientFoodModel):
|
||||
return {
|
||||
**GetterDict(name_orm),
|
||||
"extras": {x.key_name: x.value for x in name_orm.extras},
|
||||
}
|
||||
# Keep all other fields as they are
|
||||
else:
|
||||
return super().get(key, default)
|
||||
|
||||
orm_mode = True
|
||||
getter_dict = _FoodGetter
|
||||
|
||||
|
||||
class IngredientFoodPagination(PaginationBase):
|
||||
|
Loading…
x
Reference in New Issue
Block a user