mirror of
				https://github.com/mealie-recipes/mealie.git
				synced 2025-10-31 10:13:32 -04:00 
			
		
		
		
	chore: Optimize Loads on Queries (#4220)
Co-authored-by: Hayden <64056131+hay-kot@users.noreply.github.com>
This commit is contained in:
		| @@ -7,7 +7,7 @@ import sqlalchemy as sa | ||||
| from pydantic import UUID4 | ||||
| from slugify import slugify | ||||
| from sqlalchemy.exc import IntegrityError | ||||
| from sqlalchemy.orm import InstrumentedAttribute, joinedload | ||||
| from sqlalchemy.orm import InstrumentedAttribute | ||||
| from typing_extensions import Self | ||||
|  | ||||
| from mealie.db.models.recipe.category import Category | ||||
| @@ -165,15 +165,6 @@ class RepositoryRecipes(HouseholdRepositoryGeneric[Recipe, RecipeModel]): | ||||
|         pagination_result = pagination.model_copy() | ||||
|         q = sa.select(self.model) | ||||
|  | ||||
|         args = [ | ||||
|             joinedload(RecipeModel.recipe_category), | ||||
|             joinedload(RecipeModel.tags), | ||||
|             joinedload(RecipeModel.tools), | ||||
|             joinedload(RecipeModel.user), | ||||
|         ] | ||||
|  | ||||
|         q = q.options(*args) | ||||
|  | ||||
|         fltr = self._filter_builder() | ||||
|         q = q.filter_by(**fltr) | ||||
|  | ||||
| @@ -212,6 +203,8 @@ class RepositoryRecipes(HouseholdRepositoryGeneric[Recipe, RecipeModel]): | ||||
|  | ||||
|         q, count, total_pages = self.add_pagination_to_query(q, pagination_result) | ||||
|  | ||||
|         # Apply options late, so they do not get used for counting | ||||
|         q = q.options(*RecipeSummary.loader_options()) | ||||
|         try: | ||||
|             data = self.session.execute(q).scalars().unique().all() | ||||
|         except Exception as e: | ||||
|   | ||||
| @@ -14,6 +14,7 @@ from mealie.db.models.household import ( | ||||
|     ShoppingListRecipeReference, | ||||
| ) | ||||
| from mealie.db.models.recipe import IngredientFoodModel, RecipeModel | ||||
| from mealie.db.models.users.users import User | ||||
| from mealie.schema._mealie import MealieModel | ||||
| from mealie.schema._mealie.mealie_model import UpdatedAtField | ||||
| from mealie.schema._mealie.types import NoneFloat | ||||
| @@ -137,7 +138,9 @@ class ShoppingListItemOut(ShoppingListItemBase): | ||||
|             joinedload(ShoppingListItem.label), | ||||
|             joinedload(ShoppingListItem.unit), | ||||
|             selectinload(ShoppingListItem.recipe_references), | ||||
|             joinedload(ShoppingListItem.shopping_list).joinedload(ShoppingList.user), | ||||
|             joinedload(ShoppingListItem.shopping_list) | ||||
|             .joinedload(ShoppingList.user) | ||||
|             .load_only(User.household_id, User.group_id), | ||||
|         ] | ||||
|  | ||||
|  | ||||
| @@ -232,7 +235,7 @@ class ShoppingListSummary(ShoppingListSave): | ||||
|             .joinedload(ShoppingListRecipeReference.recipe) | ||||
|             .joinedload(RecipeModel.tools), | ||||
|             selectinload(ShoppingList.label_settings).joinedload(ShoppingListMultiPurposeLabel.label), | ||||
|             joinedload(ShoppingList.user), | ||||
|             joinedload(ShoppingList.user).load_only(User.household_id, User.group_id), | ||||
|         ] | ||||
|  | ||||
|  | ||||
| @@ -279,7 +282,7 @@ class ShoppingListOut(ShoppingListUpdate): | ||||
|             .joinedload(ShoppingListRecipeReference.recipe) | ||||
|             .joinedload(RecipeModel.tools), | ||||
|             selectinload(ShoppingList.label_settings).joinedload(ShoppingListMultiPurposeLabel.label), | ||||
|             joinedload(ShoppingList.user), | ||||
|             joinedload(ShoppingList.user).load_only(User.household_id, User.group_id), | ||||
|         ] | ||||
|  | ||||
|  | ||||
|   | ||||
| @@ -1,5 +1,9 @@ | ||||
| from pydantic import UUID4, ConfigDict | ||||
| from sqlalchemy.orm import joinedload | ||||
| from sqlalchemy.orm.interfaces import LoaderOption | ||||
|  | ||||
| from mealie.db.models.household.household import Household | ||||
| from mealie.db.models.household.preferences import HouseholdPreferencesModel | ||||
| from mealie.schema._mealie import MealieModel | ||||
|  | ||||
|  | ||||
| @@ -27,3 +31,9 @@ class SaveHouseholdPreferences(UpdateHouseholdPreferences): | ||||
| class ReadHouseholdPreferences(CreateHouseholdPreferences): | ||||
|     id: UUID4 | ||||
|     model_config = ConfigDict(from_attributes=True) | ||||
|  | ||||
|     @classmethod | ||||
|     def loader_options(cls) -> list[LoaderOption]: | ||||
|         return [ | ||||
|             joinedload(HouseholdPreferencesModel.household).load_only(Household.group_id), | ||||
|         ] | ||||
|   | ||||
| @@ -10,6 +10,7 @@ from sqlalchemy.orm.interfaces import LoaderOption | ||||
|  | ||||
| from mealie.db.models.household import GroupMealPlan | ||||
| from mealie.db.models.recipe import RecipeModel | ||||
| from mealie.db.models.users.users import User | ||||
| from mealie.schema._mealie import MealieModel | ||||
| from mealie.schema.recipe.recipe import RecipeSummary | ||||
| from mealie.schema.response.pagination import PaginationBase | ||||
| @@ -66,7 +67,7 @@ class ReadPlanEntry(UpdatePlanEntry): | ||||
|             selectinload(GroupMealPlan.recipe).joinedload(RecipeModel.recipe_category), | ||||
|             selectinload(GroupMealPlan.recipe).joinedload(RecipeModel.tags), | ||||
|             selectinload(GroupMealPlan.recipe).joinedload(RecipeModel.tools), | ||||
|             selectinload(GroupMealPlan.user), | ||||
|             selectinload(GroupMealPlan.user).load_only(User.household_id), | ||||
|         ] | ||||
|  | ||||
|  | ||||
|   | ||||
| @@ -14,6 +14,7 @@ from sqlalchemy.orm import Session, joinedload, selectinload | ||||
| from sqlalchemy.orm.interfaces import LoaderOption | ||||
|  | ||||
| from mealie.core.config import get_app_dirs | ||||
| from mealie.db.models.users.users import User | ||||
| from mealie.schema._mealie import MealieModel, SearchType | ||||
| from mealie.schema._mealie.mealie_model import UpdatedAtField | ||||
| from mealie.schema.response.pagination import PaginationBase | ||||
| @@ -121,6 +122,15 @@ class RecipeSummary(MealieModel): | ||||
|  | ||||
|         return val | ||||
|  | ||||
|     @classmethod | ||||
|     def loader_options(cls) -> list[LoaderOption]: | ||||
|         return [ | ||||
|             joinedload(RecipeModel.recipe_category), | ||||
|             joinedload(RecipeModel.tags), | ||||
|             joinedload(RecipeModel.tools), | ||||
|             joinedload(RecipeModel.user).load_only(User.household_id), | ||||
|         ] | ||||
|  | ||||
|  | ||||
| class RecipePagination(PaginationBase): | ||||
|     items: list[RecipeSummary] | ||||
|   | ||||
| @@ -9,6 +9,7 @@ from sqlalchemy.orm.interfaces import LoaderOption | ||||
|  | ||||
| from mealie.core.config import get_app_dirs | ||||
| from mealie.db.models.recipe.recipe_timeline import RecipeTimelineEvent | ||||
| from mealie.db.models.users.users import User | ||||
| from mealie.schema._mealie import MealieModel | ||||
| from mealie.schema._mealie.mealie_model import UpdatedAtField | ||||
| from mealie.schema.recipe.recipe import Recipe | ||||
| @@ -67,7 +68,7 @@ class RecipeTimelineEventOut(RecipeTimelineEventCreate): | ||||
|     def loader_options(cls) -> list[LoaderOption]: | ||||
|         return [ | ||||
|             joinedload(RecipeTimelineEvent.recipe), | ||||
|             joinedload(RecipeTimelineEvent.user), | ||||
|             joinedload(RecipeTimelineEvent.user).load_only(User.household_id, User.group_id), | ||||
|         ] | ||||
|  | ||||
|     @classmethod | ||||
|   | ||||
| @@ -8,7 +8,9 @@ from sqlalchemy.orm import joinedload, selectinload | ||||
| from sqlalchemy.orm.interfaces import LoaderOption | ||||
|  | ||||
| from mealie.core.config import get_app_dirs, get_app_settings | ||||
| from mealie.db.models.recipe.recipe import RecipeModel | ||||
| from mealie.db.models.users import User | ||||
| from mealie.db.models.users.user_to_recipe import UserToRecipe | ||||
| from mealie.db.models.users.users import AuthMethod, LongLiveToken | ||||
| from mealie.schema._mealie import MealieModel | ||||
| from mealie.schema.group.group_preferences import ReadGroupPreferences | ||||
| @@ -88,6 +90,12 @@ class UserRatingUpdate(MealieModel): | ||||
| class UserRatingOut(UserRatingCreate): | ||||
|     id: UUID4 | ||||
|  | ||||
|     @classmethod | ||||
|     def loader_options(cls) -> list[LoaderOption]: | ||||
|         return [ | ||||
|             joinedload(UserToRecipe.recipe).joinedload(RecipeModel.user).load_only(User.household_id, User.group_id) | ||||
|         ] | ||||
|  | ||||
|  | ||||
| class UserRatings(BaseModel, Generic[DataT]): | ||||
|     ratings: list[DataT] | ||||
|   | ||||
		Reference in New Issue
	
	Block a user