mirror of
https://github.com/mealie-recipes/mealie.git
synced 2025-07-09 03:04:54 -04:00
fix: all recipes performance regressions (#2062)
* Move recipe validations from RecipeSummary to Recipe * fix RepositoryRecipes loading recipes with ingredients even when load_food is False * Add eager loading of ingredient units * fix trying to instantiate PaginationBase with concrete type not being valid for mypy * fix linting issue
This commit is contained in:
parent
2340ee5bfb
commit
49bd420c10
@ -16,9 +16,15 @@ from mealie.db.models.recipe.tag import Tag
|
|||||||
from mealie.db.models.recipe.tool import Tool
|
from mealie.db.models.recipe.tool import Tool
|
||||||
from mealie.schema.cookbook.cookbook import ReadCookBook
|
from mealie.schema.cookbook.cookbook import ReadCookBook
|
||||||
from mealie.schema.recipe import Recipe
|
from mealie.schema.recipe import Recipe
|
||||||
from mealie.schema.recipe.recipe import RecipeCategory, RecipePagination, RecipeSummary, RecipeTag, RecipeTool
|
from mealie.schema.recipe.recipe import (
|
||||||
|
RecipeCategory,
|
||||||
|
RecipeSummary,
|
||||||
|
RecipeSummaryWithIngredients,
|
||||||
|
RecipeTag,
|
||||||
|
RecipeTool,
|
||||||
|
)
|
||||||
from mealie.schema.recipe.recipe_category import CategoryBase, TagBase
|
from mealie.schema.recipe.recipe_category import CategoryBase, TagBase
|
||||||
from mealie.schema.response.pagination import PaginationQuery
|
from mealie.schema.response.pagination import PaginationBase, PaginationQuery
|
||||||
|
|
||||||
from .repository_generic import RepositoryGeneric
|
from .repository_generic import RepositoryGeneric
|
||||||
|
|
||||||
@ -139,7 +145,7 @@ class RepositoryRecipes(RepositoryGeneric[Recipe, RecipeModel]):
|
|||||||
categories: list[UUID4 | str] | None = None,
|
categories: list[UUID4 | str] | None = None,
|
||||||
tags: list[UUID4 | str] | None = None,
|
tags: list[UUID4 | str] | None = None,
|
||||||
tools: list[UUID4 | str] | None = None,
|
tools: list[UUID4 | str] | None = None,
|
||||||
) -> RecipePagination:
|
) -> PaginationBase[RecipeSummary]:
|
||||||
q = self.session.query(self.model)
|
q = self.session.query(self.model)
|
||||||
|
|
||||||
args = [
|
args = [
|
||||||
@ -150,6 +156,10 @@ class RepositoryRecipes(RepositoryGeneric[Recipe, RecipeModel]):
|
|||||||
|
|
||||||
if load_food:
|
if load_food:
|
||||||
args.append(joinedload(RecipeModel.recipe_ingredient).options(joinedload(RecipeIngredient.food)))
|
args.append(joinedload(RecipeModel.recipe_ingredient).options(joinedload(RecipeIngredient.food)))
|
||||||
|
args.append(joinedload(RecipeModel.recipe_ingredient).options(joinedload(RecipeIngredient.unit)))
|
||||||
|
item_class = RecipeSummaryWithIngredients
|
||||||
|
else:
|
||||||
|
item_class = RecipeSummary
|
||||||
|
|
||||||
q = q.options(*args)
|
q = q.options(*args)
|
||||||
|
|
||||||
@ -201,12 +211,13 @@ class RepositoryRecipes(RepositoryGeneric[Recipe, RecipeModel]):
|
|||||||
self.session.rollback()
|
self.session.rollback()
|
||||||
raise e
|
raise e
|
||||||
|
|
||||||
return RecipePagination(
|
items = [item_class.from_orm(item) for item in data]
|
||||||
|
return PaginationBase(
|
||||||
page=pagination.page,
|
page=pagination.page,
|
||||||
per_page=pagination.per_page,
|
per_page=pagination.per_page,
|
||||||
total=count,
|
total=count,
|
||||||
total_pages=total_pages,
|
total_pages=total_pages,
|
||||||
items=data,
|
items=items,
|
||||||
)
|
)
|
||||||
|
|
||||||
def get_by_categories(self, categories: list[RecipeCategory]) -> list[RecipeSummary]:
|
def get_by_categories(self, categories: list[RecipeCategory]) -> list[RecipeSummary]:
|
||||||
|
@ -25,13 +25,21 @@ from mealie.routes._base.mixins import HttpRepo
|
|||||||
from mealie.routes._base.routers import MealieCrudRoute, UserAPIRouter
|
from mealie.routes._base.routers import MealieCrudRoute, UserAPIRouter
|
||||||
from mealie.schema.cookbook.cookbook import ReadCookBook
|
from mealie.schema.cookbook.cookbook import ReadCookBook
|
||||||
from mealie.schema.recipe import Recipe, RecipeImageTypes, ScrapeRecipe
|
from mealie.schema.recipe import Recipe, RecipeImageTypes, ScrapeRecipe
|
||||||
from mealie.schema.recipe.recipe import CreateRecipe, CreateRecipeByUrlBulk, RecipePagination, RecipePaginationQuery
|
from mealie.schema.recipe.recipe import (
|
||||||
|
CreateRecipe,
|
||||||
|
CreateRecipeByUrlBulk,
|
||||||
|
RecipePagination,
|
||||||
|
RecipePaginationQuery,
|
||||||
|
RecipeSummary,
|
||||||
|
RecipeSummaryWithIngredients,
|
||||||
|
)
|
||||||
from mealie.schema.recipe.recipe_asset import RecipeAsset
|
from mealie.schema.recipe.recipe_asset import RecipeAsset
|
||||||
from mealie.schema.recipe.recipe_ingredient import RecipeIngredient
|
from mealie.schema.recipe.recipe_ingredient import RecipeIngredient
|
||||||
from mealie.schema.recipe.recipe_scraper import ScrapeRecipeTest
|
from mealie.schema.recipe.recipe_scraper import ScrapeRecipeTest
|
||||||
from mealie.schema.recipe.recipe_settings import RecipeSettings
|
from mealie.schema.recipe.recipe_settings import RecipeSettings
|
||||||
from mealie.schema.recipe.recipe_step import RecipeStep
|
from mealie.schema.recipe.recipe_step import RecipeStep
|
||||||
from mealie.schema.recipe.request_helpers import RecipeDuplicate, RecipeZipTokenResponse, UpdateImageResponse
|
from mealie.schema.recipe.request_helpers import RecipeDuplicate, RecipeZipTokenResponse, UpdateImageResponse
|
||||||
|
from mealie.schema.response import PaginationBase
|
||||||
from mealie.schema.response.responses import ErrorResponse
|
from mealie.schema.response.responses import ErrorResponse
|
||||||
from mealie.services import urls
|
from mealie.services import urls
|
||||||
from mealie.services.event_bus_service.event_types import (
|
from mealie.services.event_bus_service.event_types import (
|
||||||
@ -232,7 +240,7 @@ class RecipeController(BaseRecipeController):
|
|||||||
# ==================================================================================================================
|
# ==================================================================================================================
|
||||||
# CRUD Operations
|
# CRUD Operations
|
||||||
|
|
||||||
@router.get("", response_model=RecipePagination)
|
@router.get("", response_model=PaginationBase[RecipeSummary | RecipeSummaryWithIngredients])
|
||||||
def get_all(
|
def get_all(
|
||||||
self,
|
self,
|
||||||
request: Request,
|
request: Request,
|
||||||
|
@ -91,8 +91,6 @@ class RecipeSummary(MealieModel):
|
|||||||
rating: int | None
|
rating: int | None
|
||||||
org_url: str | None = Field(None, alias="orgURL")
|
org_url: str | None = Field(None, alias="orgURL")
|
||||||
|
|
||||||
recipe_ingredient: list[RecipeIngredient] | None = []
|
|
||||||
|
|
||||||
date_added: datetime.date | None
|
date_added: datetime.date | None
|
||||||
date_updated: datetime.datetime | None
|
date_updated: datetime.datetime | None
|
||||||
|
|
||||||
@ -103,29 +101,9 @@ class RecipeSummary(MealieModel):
|
|||||||
class Config:
|
class Config:
|
||||||
orm_mode = True
|
orm_mode = True
|
||||||
|
|
||||||
@validator("tags", always=True, pre=True, allow_reuse=True)
|
|
||||||
def validate_tags(cats: list[Any]): # type: ignore
|
|
||||||
if isinstance(cats, list) and cats and isinstance(cats[0], str):
|
|
||||||
return [RecipeTag(id=uuid4(), name=c, slug=slugify(c)) for c in cats]
|
|
||||||
return cats
|
|
||||||
|
|
||||||
@validator("recipe_category", always=True, pre=True, allow_reuse=True)
|
class RecipeSummaryWithIngredients(RecipeSummary):
|
||||||
def validate_categories(cats: list[Any]): # type: ignore
|
recipe_ingredient: list[RecipeIngredient] | None = []
|
||||||
if isinstance(cats, list) and cats and isinstance(cats[0], str):
|
|
||||||
return [RecipeCategory(id=uuid4(), name=c, slug=slugify(c)) for c in cats]
|
|
||||||
return cats
|
|
||||||
|
|
||||||
@validator("group_id", always=True, pre=True, allow_reuse=True)
|
|
||||||
def validate_group_id(group_id: Any):
|
|
||||||
if isinstance(group_id, int):
|
|
||||||
return uuid4()
|
|
||||||
return group_id
|
|
||||||
|
|
||||||
@validator("user_id", always=True, pre=True, allow_reuse=True)
|
|
||||||
def validate_user_id(user_id: Any):
|
|
||||||
if isinstance(user_id, int):
|
|
||||||
return uuid4()
|
|
||||||
return user_id
|
|
||||||
|
|
||||||
|
|
||||||
class RecipePaginationQuery(PaginationQuery):
|
class RecipePaginationQuery(PaginationQuery):
|
||||||
@ -205,8 +183,33 @@ class Recipe(RecipeSummary):
|
|||||||
|
|
||||||
return recipe_ingredient
|
return recipe_ingredient
|
||||||
|
|
||||||
|
@validator("tags", always=True, pre=True, allow_reuse=True)
|
||||||
|
def validate_tags(cats: list[Any]): # type: ignore
|
||||||
|
if isinstance(cats, list) and cats and isinstance(cats[0], str):
|
||||||
|
return [RecipeTag(id=uuid4(), name=c, slug=slugify(c)) for c in cats]
|
||||||
|
return cats
|
||||||
|
|
||||||
|
@validator("recipe_category", always=True, pre=True, allow_reuse=True)
|
||||||
|
def validate_categories(cats: list[Any]): # type: ignore
|
||||||
|
if isinstance(cats, list) and cats and isinstance(cats[0], str):
|
||||||
|
return [RecipeCategory(id=uuid4(), name=c, slug=slugify(c)) for c in cats]
|
||||||
|
return cats
|
||||||
|
|
||||||
|
@validator("group_id", always=True, pre=True, allow_reuse=True)
|
||||||
|
def validate_group_id(group_id: Any):
|
||||||
|
if isinstance(group_id, int):
|
||||||
|
return uuid4()
|
||||||
|
return group_id
|
||||||
|
|
||||||
|
@validator("user_id", always=True, pre=True, allow_reuse=True)
|
||||||
|
def validate_user_id(user_id: Any):
|
||||||
|
if isinstance(user_id, int):
|
||||||
|
return uuid4()
|
||||||
|
return user_id
|
||||||
|
|
||||||
|
|
||||||
from mealie.schema.recipe.recipe_ingredient import RecipeIngredient # noqa: E402
|
from mealie.schema.recipe.recipe_ingredient import RecipeIngredient # noqa: E402
|
||||||
|
|
||||||
RecipeSummary.update_forward_refs()
|
RecipeSummary.update_forward_refs()
|
||||||
|
RecipeSummaryWithIngredients.update_forward_refs()
|
||||||
Recipe.update_forward_refs()
|
Recipe.update_forward_refs()
|
||||||
|
Loading…
x
Reference in New Issue
Block a user