chore: Optimize Loads on Queries (#4220)

Co-authored-by: Hayden <64056131+hay-kot@users.noreply.github.com>
This commit is contained in:
Michael Genson 2024-09-19 23:10:10 -05:00 committed by GitHub
parent e971efd809
commit ba363da251
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 41 additions and 15 deletions

View File

@ -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:

View File

@ -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),
]

View File

@ -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),
]

View File

@ -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),
]

View File

@ -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]

View File

@ -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

View File

@ -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]