Always load product when loading ingredient

This commit is contained in:
jableader 2024-01-17 23:51:07 +11:00
parent 7c9c24189b
commit 24f97230f0
3 changed files with 23 additions and 25 deletions

View file

@ -14,7 +14,7 @@ class Ingredient(BaseModel):
product_id: Optional[int] = None product_id: Optional[int] = None
recipe_id: Optional[int] = None recipe_id: Optional[int] = None
meal_id: Optional[int] = None meal_id: Optional[int] = None
product: Product = None product: Optional[Product] = None
async def create(conn): async def create(conn):
await conn.execute(''' await conn.execute('''
@ -42,17 +42,29 @@ async def insert_ingredient(conn, ingredient: Ingredient):
ingredient.id = cursor.lastrowid ingredient.id = cursor.lastrowid
async def find_ingredients_by_recipe_id(conn, recipe_id: int) -> List[Ingredient]: async def find_ingredients_by_recipe_id(conn, recipe_id: int) -> List[Ingredient]:
ingredient_keys = [f'ingredient.{key}' for key in Ingredient.KEYS]
product_keys = [f'product.{key}' for key in Product.KEYS]
async with conn.execute(f''' async with conn.execute(f'''
SELECT {','.join(Ingredient.KEYS)} FROM Ingredient SELECT {','.join(ingredient_keys + product_keys)} FROM Ingredient
LEFT JOIN Product ON Ingredient.product_id = Product.id
WHERE recipe_id = ? WHERE recipe_id = ?
''', (recipe_id,)) as cursor: ''', (recipe_id,)) as cursor:
async for row in cursor: async for row in cursor:
yield Ingredient(**{k:v for k,v in zip(Ingredient.KEYS, row)}) product_keys = {k:v for k,v in zip(Product.KEYS, row[len(Ingredient.KEYS):])}
product = Product(**product_keys) if product_keys['id'] else None
yield Ingredient(**{k:v for k,v in zip(Ingredient.KEYS, row[:len(Ingredient.KEYS)])}, product=product)
async def find_ingredients_by_meal_id(conn, meal_id: int) -> List[Ingredient]: async def find_ingredients_by_meal_id(conn, meal_id: int) -> List[Ingredient]:
ingredient_keys = [f'ingredient.{key}' for key in Ingredient.KEYS]
product_keys = [f'product.{key}' for key in Product.KEYS]
async with conn.execute(f''' async with conn.execute(f'''
SELECT {','.join(Ingredient.KEYS)} FROM Ingredient SELECT {','.join(ingredient_keys + product_keys)} FROM Ingredient
LEFT JOIN Product ON Ingredient.product_id = Product.id
WHERE meal_id = ? WHERE meal_id = ?
''', (meal_id,)) as cursor: ''', (meal_id,)) as cursor:
async for row in cursor: async for row in cursor:
yield Ingredient(**{k:v for k,v in zip(Ingredient.KEYS, row)}) product_keys = {k:v for k,v in zip(Product.KEYS, row[len(Ingredient.KEYS):])}
product = Product(**product_keys) if product_keys['id'] else None
yield Ingredient(**{k:v for k,v in zip(Ingredient.KEYS, row[:len(Ingredient.KEYS)])}, product=product)

View file

@ -1,7 +1,7 @@
from typing import List, ClassVar from typing import List, ClassVar
from pydantic import BaseModel from pydantic import BaseModel
from persons import Person from persons import Person
from ingredients import Ingredient, insert_ingredient from ingredients import Ingredient, insert_ingredient, find_ingredients_by_meal_id
from products import Product from products import Product
from recipes import Recipe, row_to_recipe from recipes import Recipe, row_to_recipe
@ -130,18 +130,8 @@ async def load_recipes(conn, meal: Meal) -> None:
meal.recipes.append(row_to_recipe(zip(Recipe.KEYS, row))) meal.recipes.append(row_to_recipe(zip(Recipe.KEYS, row)))
async def load_extra_ingredients(conn, meal: Meal) -> None: async def load_extra_ingredients(conn, meal: Meal) -> None:
ingredient_cols = [f'Ingredient.{k}' for k in Ingredient.KEYS] async for ingredient in find_ingredients_by_meal_id(conn, meal.id):
product_cols = [f'Product.{k}' for k in Product.KEYS] meal.extra_ingredients.append(ingredient)
async with conn.execute(f'''
SELECT {','.join(ingredient_cols + product_cols)} FROM Ingredient
JOIN Product ON Ingredient.product_id = Product.id
WHERE meal_id = ?
''', (meal.id,)) as cursor:
async for row in cursor:
ingredient = Ingredient(**{k:v for k,v in zip(Ingredient.KEYS, row[:len(Ingredient.KEYS)])})
ingredient.product = Product(**{k:v for k,v in zip(Product.KEYS, row[len(Ingredient.KEYS):])})
meal.extra_ingredients.append(ingredient)
async def delete_meal(conn, meal_id: int) -> None: async def delete_meal(conn, meal_id: int) -> None:
await conn.execute(''' await conn.execute('''

View file

@ -1,6 +1,6 @@
import json import json
from ingredients import Ingredient from ingredients import Ingredient, find_ingredients_by_recipe_id
from pydantic import BaseModel, Field from pydantic import BaseModel, Field
from typing import List, ClassVar, Tuple from typing import List, ClassVar, Tuple
@ -61,9 +61,5 @@ async def get_all(conn) -> List[Recipe]:
yield row_to_recipe(zip(Recipe.KEYS, row)) yield row_to_recipe(zip(Recipe.KEYS, row))
async def load_ingredients(conn, recipe: Recipe): async def load_ingredients(conn, recipe: Recipe):
async with conn.execute(f''' async for ingredient in find_ingredients_by_recipe_id(conn, recipe.id):
SELECT {','.join(Ingredient.KEYS)} FROM Ingredient recipe.ingredients.append(ingredient)
WHERE recipe_id = ?
''', (recipe.id,)) as cursor:
async for row in cursor:
recipe.ingredients.append(Ingredient(**{k:v for k,v in zip(Ingredient.KEYS, row)}))