munch-ease-backend/recipes/db.py

103 lines
3.3 KiB
Python
Raw Normal View History

2024-01-13 08:44:07 +00:00
import json
2024-01-13 03:21:38 +00:00
import aiosqlite
2024-01-13 07:44:48 +00:00
from products import Product
2024-01-13 03:21:38 +00:00
from pydantic import BaseModel
2024-01-13 05:40:10 +00:00
from typing import List, ClassVar, Optional
2024-01-13 03:21:38 +00:00
class Ingredient(BaseModel):
2024-01-13 05:40:10 +00:00
KEYS: ClassVar[List[str]] = ['id', 'name', 'line', 'preparation', 'unit', 'quantity', 'product_id', 'recipe_id']
2024-01-13 03:21:38 +00:00
id: int
name: str
line: str
unit: str
quantity: float
preparation: str
2024-01-13 05:40:10 +00:00
product_id: Optional[int] = None
recipe_id: Optional[int] = None
2024-01-13 03:21:38 +00:00
product: Product = None
class Recipe(BaseModel):
2024-01-13 08:44:07 +00:00
KEYS: ClassVar[List[str]] = ['id', 'name', 'link', 'image_urls', 'raw_data']
2024-01-13 03:21:38 +00:00
id: int
name: str
link: str
raw_data: str
2024-01-13 08:44:07 +00:00
image_urls: List[str] = []
2024-01-13 03:21:38 +00:00
ingredients: List[Ingredient] = []
async def create(conn):
await conn.execute('''
CREATE TABLE IF NOT EXISTS Recipe (
id INTEGER PRIMARY KEY,
name TEXT,
link TEXT,
2024-01-13 08:44:07 +00:00
image_urls TEXT,
2024-01-13 03:21:38 +00:00
raw_data TEXT
);''')
await conn.execute('''
CREATE TABLE IF NOT EXISTS Ingredient (
id INTEGER PRIMARY KEY,
name TEXT,
line TEXT,
preparation TEXT,
unit TEXT,
quantity REAL,
product_id INTEGER,
recipe_id INTEGER,
FOREIGN KEY (product_id) REFERENCES Product(id),
FOREIGN KEY (recipe_id) REFERENCES Recipe(id)
);''')
async def insert_ingredient(conn, ingredient: Ingredient):
async with conn.execute('''
INSERT INTO Ingredient (name, line, preparation, unit, quantity, product_id, recipe_id)
VALUES (?, ?, ?, ?, ?, ?, ?)
''', (ingredient.name, ingredient.line, ingredient.preparation, ingredient.unit, ingredient.quantity, ingredient.product_id, ingredient.recipe_id)) as cursor:
ingredient.id = cursor.lastrowid
async def insert_recipe(conn, recipe: Recipe):
async with conn.execute('''
2024-01-13 08:44:07 +00:00
INSERT INTO Recipe (name, link, raw_data, image_urls)
VALUES (?, ?, ?, ?)
2024-01-13 08:44:07 +00:00
''', (recipe.name, recipe.link, recipe.raw_data, json.dumps(recipe.image_urls))) as cursor:
2024-01-13 03:21:38 +00:00
recipe.id = cursor.lastrowid
2024-01-13 08:44:07 +00:00
def row_to_recipe(row) -> Recipe:
d = {k:v for k,v in zip(Recipe.KEYS, row)}
d['image_urls'] = json.loads(d['image_urls'])
2024-01-13 08:44:07 +00:00
return Recipe(**d)
2024-01-13 03:21:38 +00:00
async def find_recipe_by_id(conn, recipe_id: int) -> Recipe:
async with conn.execute(f'''
SELECT {','.join(Recipe.KEYS)} FROM Recipe
WHERE id = ?
LIMIT 1
''', (recipe_id,)) as cursor:
async for row in cursor:
2024-01-13 08:44:07 +00:00
return row_to_recipe(row)
2024-01-13 03:21:38 +00:00
2024-01-13 06:59:35 +00:00
async def find_ingredients_by_recipe_id(conn, recipe_id: int) -> List[Ingredient]:
2024-01-13 03:21:38 +00:00
async with conn.execute(f'''
SELECT {','.join(Ingredient.KEYS)} FROM Ingredient
WHERE recipe_id = ?
''', (recipe_id,)) as cursor:
async for row in cursor:
2024-01-13 08:44:07 +00:00
yield Ingredient(**{k:v for k,v in zip(Ingredient.KEYS, row)})
async def find_recipes_by_name(conn, name: str) -> List[Recipe]:
async with conn.execute(f'''
SELECT {','.join(Recipe.KEYS)} FROM Recipe
WHERE name LIKE ?
''', (f'%{name}%',)) as cursor:
async for row in cursor:
yield row_to_recipe(row)
2024-01-13 08:44:07 +00:00
async def get_all(conn) -> List[Recipe]:
async with conn.execute(f'''
SELECT {','.join(Recipe.KEYS)} FROM Recipe
''') as cursor:
async for row in cursor:
yield row_to_recipe(row)