From 24f97230f035a3fb925451da8aacbb48a86b3668 Mon Sep 17 00:00:00 2001 From: jableader Date: Wed, 17 Jan 2024 23:51:07 +1100 Subject: [PATCH] Always load product when loading ingredient --- ingredients/db.py | 22 +++++++++++++++++----- meals/db.py | 16 +++------------- recipes/db.py | 10 +++------- 3 files changed, 23 insertions(+), 25 deletions(-) diff --git a/ingredients/db.py b/ingredients/db.py index 1cbf593..d80b50b 100644 --- a/ingredients/db.py +++ b/ingredients/db.py @@ -14,7 +14,7 @@ class Ingredient(BaseModel): product_id: Optional[int] = None recipe_id: Optional[int] = None meal_id: Optional[int] = None - product: Product = None + product: Optional[Product] = None async def create(conn): await conn.execute(''' @@ -42,17 +42,29 @@ async def insert_ingredient(conn, ingredient: Ingredient): ingredient.id = cursor.lastrowid 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''' - 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 = ? ''', (recipe_id,)) as 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]: + 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''' - 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 = ? ''', (meal_id,)) as cursor: async for row in cursor: - yield Ingredient(**{k:v for k,v in zip(Ingredient.KEYS, row)}) \ No newline at end of file + 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) \ No newline at end of file diff --git a/meals/db.py b/meals/db.py index 59aa983..d85a5cd 100644 --- a/meals/db.py +++ b/meals/db.py @@ -1,7 +1,7 @@ from typing import List, ClassVar from pydantic import BaseModel 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 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))) async def load_extra_ingredients(conn, meal: Meal) -> None: - ingredient_cols = [f'Ingredient.{k}' for k in Ingredient.KEYS] - product_cols = [f'Product.{k}' for k in Product.KEYS] - - 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 for ingredient in find_ingredients_by_meal_id(conn, meal.id): + meal.extra_ingredients.append(ingredient) async def delete_meal(conn, meal_id: int) -> None: await conn.execute(''' diff --git a/recipes/db.py b/recipes/db.py index 0ab4791..20b5a52 100644 --- a/recipes/db.py +++ b/recipes/db.py @@ -1,6 +1,6 @@ import json -from ingredients import Ingredient +from ingredients import Ingredient, find_ingredients_by_recipe_id from pydantic import BaseModel, Field 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)) async def load_ingredients(conn, recipe: Recipe): - async with conn.execute(f''' - SELECT {','.join(Ingredient.KEYS)} FROM 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)})) \ No newline at end of file + async for ingredient in find_ingredients_by_recipe_id(conn, recipe.id): + recipe.ingredients.append(ingredient) \ No newline at end of file