From 00c469263caf1fd461ac8359d80b4c4d79b8f45b Mon Sep 17 00:00:00 2001 From: hay-kot Date: Mon, 8 Feb 2021 15:07:39 -0900 Subject: [PATCH] category import errors on import --- mealie/db/db_mealplan.py | 63 --------------------------- mealie/db/db_recipes.py | 68 ------------------------------ mealie/db/db_settings.py | 44 ------------------- mealie/db/db_themes.py | 56 ------------------------ mealie/db/sql/recipe_models.py | 32 +++++++++++--- mealie/services/backups/imports.py | 19 ++++++++- 6 files changed, 42 insertions(+), 240 deletions(-) delete mode 100644 mealie/db/db_mealplan.py delete mode 100644 mealie/db/db_recipes.py delete mode 100644 mealie/db/db_settings.py delete mode 100644 mealie/db/db_themes.py diff --git a/mealie/db/db_mealplan.py b/mealie/db/db_mealplan.py deleted file mode 100644 index 96907390f..000000000 --- a/mealie/db/db_mealplan.py +++ /dev/null @@ -1,63 +0,0 @@ -from typing import List - -from app_config import USE_MONGO, USE_SQL - -from db.db_base import BaseDocument -from db.db_setup import USE_MONGO, USE_SQL -from db.mongo.meal_models import MealDocument, MealPlanDocument -from db.sql.db_session import create_session -from db.sql.meal_models import MealPlanModel - - -class _Meals(BaseDocument): - def __init__(self) -> None: - self.primary_key = "uid" - if USE_SQL: - self.sql_model = MealPlanModel - self.create_session = create_session - - self.document = MealPlanDocument - - @staticmethod - def _process_meals(meals: List[dict]) -> List[MealDocument]: - """Turns a list of Meals in dictionary form into a list of - MealDocuments that can be attached to a MealPlanDocument - - - Args: \n - meals (List[dict]): From a Pydantic Class in meal_services.py \n - - Returns: - a List of MealDocuments - """ - meal_docs = [] - for meal in meals: - meal_doc = MealDocument(**meal) - meal_docs.append(meal_doc) - - return meal_docs - - def save_new_mongo(self, plan_data: dict) -> None: - """Saves a new meal plan into the database - - Args: \n - plan_data (dict): From a Pydantic Class in meal_services.py \n - """ - - if USE_MONGO: - plan_data["meals"] = _Meals._process_meals(plan_data["meals"]) - document = self.document(**plan_data) - - document.save() - elif USE_SQL: - pass - - def update_mongo(self, uid: str, plan_data: dict) -> dict: - if USE_MONGO: - document = self.document.objects.get(uid=uid) - if document: - new_meals = _Meals._process_meals(plan_data["meals"]) - document.update(set__meals=new_meals) - document.save() - elif USE_SQL: - pass diff --git a/mealie/db/db_recipes.py b/mealie/db/db_recipes.py deleted file mode 100644 index 945ee079d..000000000 --- a/mealie/db/db_recipes.py +++ /dev/null @@ -1,68 +0,0 @@ -from app_config import USE_MONGO, USE_SQL - -from db.db_base import BaseDocument -from db.mongo.recipe_models import RecipeDocument -from db.sql.db_session import create_session -from db.sql.recipe_models import RecipeModel - - -class _Recipes(BaseDocument): - def __init__(self) -> None: - self.primary_key = "slug" - if USE_SQL: - self.sql_model = RecipeModel - self.create_session = create_session - else: - self.document = RecipeDocument - - def save_new_sql(self, recipe_data: dict): - session = self.create_session() - new_recipe = self.sql_model(**recipe_data) - session.add(new_recipe) - session.commit() - - return recipe_data - - def update_mongo(self, slug: str, new_data: dict) -> None: - if USE_MONGO: - document = self.document.objects.get(slug=slug) - - if document: - document.update(set__name=new_data.get("name")) - document.update(set__description=new_data.get("description")) - document.update(set__image=new_data.get("image")) - document.update(set__recipeYield=new_data.get("recipeYield")) - document.update(set__recipeIngredient=new_data.get("recipeIngredient")) - document.update( - set__recipeInstructions=new_data.get("recipeInstructions") - ) - document.update(set__totalTime=new_data.get("totalTime")) - - document.update(set__slug=new_data.get("slug")) - document.update(set__categories=new_data.get("categories")) - document.update(set__tags=new_data.get("tags")) - document.update(set__notes=new_data.get("notes")) - document.update(set__orgURL=new_data.get("orgURL")) - document.update(set__rating=new_data.get("rating")) - document.update(set__extras=new_data.get("extras")) - document.save() - - return new_data - # elif USE_SQL: - # session, recipe = self._query_one(match_value=slug) - # recipe.update(session=session, **new_data) - # recipe_dict = recipe.dict() - # session.commit() - - # session.close() - - # return recipe_dict - - def update_image(self, slug: str, extension: str) -> None: - if USE_MONGO: - document = self.document.objects.get(slug=slug) - - if document: - document.update(set__image=f"{slug}.{extension}") - elif USE_SQL: - pass diff --git a/mealie/db/db_settings.py b/mealie/db/db_settings.py deleted file mode 100644 index 2f3089500..000000000 --- a/mealie/db/db_settings.py +++ /dev/null @@ -1,44 +0,0 @@ -from app_config import USE_MONGO, USE_SQL - -from db.db_base import BaseDocument -from db.db_setup import USE_MONGO, USE_SQL -from db.mongo.settings_models import SiteSettingsDocument, WebhooksDocument -from db.sql.db_session import create_session -from db.sql.settings_models import SiteSettingsModel - - -class _Settings(BaseDocument): - def __init__(self) -> None: - - self.primary_key = "name" - - if USE_SQL: - self.sql_model = SiteSettingsModel - self.create_session = create_session - - self.document = SiteSettingsDocument - - def save_new(self, main: dict, webhooks: dict) -> str: - - if USE_MONGO: - main["webhooks"] = WebhooksDocument(**webhooks) - new_doc = self.document(**main) - return new_doc.save() - - elif USE_SQL: - session = create_session() - new_settings = self.sql_model(main.get("name"), webhooks) - - session.add(new_settings) - session.commit() - - return new_settings.dict() - - def update_mongo(self, name: str, new_data: dict) -> dict: - if USE_MONGO: - document = self.document.objects.get(name=name) - if document: - document.update(set__webhooks=WebhooksDocument(**new_data["webhooks"])) - document.save() - elif USE_SQL: - return diff --git a/mealie/db/db_themes.py b/mealie/db/db_themes.py deleted file mode 100644 index 14a378b76..000000000 --- a/mealie/db/db_themes.py +++ /dev/null @@ -1,56 +0,0 @@ -from app_config import USE_MONGO, USE_SQL - -from db.db_base import BaseDocument -from db.db_setup import USE_MONGO, USE_SQL -from db.mongo.settings_models import SiteThemeDocument, ThemeColorsDocument -from db.sql.db_session import create_session -from db.sql.theme_models import SiteThemeModel - - -class _Themes(BaseDocument): - def __init__(self) -> None: - self.primary_key = "name" - if USE_SQL: - self.sql_model = SiteThemeModel - self.create_session = create_session - else: - self.document = SiteThemeDocument - - def save_new(self, theme_data: dict) -> None: - if USE_MONGO: - theme_data["colors"] = ThemeColorsDocument(**theme_data["colors"]) - - document = self.document(**theme_data) - - document.save() - elif USE_SQL: - session = self.create_session() - new_theme = self.sql_model(**theme_data) - - session.add(new_theme) - session.commit() - - return_data = new_theme.dict() - - session.close() - return return_data - - def update(self, data: dict) -> dict: - if USE_MONGO: - colors = ThemeColorsDocument(**data["colors"]) - theme_document = self.document.objects.get(name=data.get("name")) - - if theme_document: - theme_document.update(set__colors=colors) - theme_document.save() - else: - raise Exception("No database entry was found to update") - - elif USE_SQL: - session, theme_model = self._query_one( - match_value=data["name"], match_key="name" - ) - - theme_model.update(**data) - session.commit() - session.close() diff --git a/mealie/db/sql/recipe_models.py b/mealie/db/sql/recipe_models.py index 0587947ab..14f30f004 100644 --- a/mealie/db/sql/recipe_models.py +++ b/mealie/db/sql/recipe_models.py @@ -7,6 +7,7 @@ import sqlalchemy.orm as orm from db.sql.model_base import BaseMixins, SqlAlchemyBase from slugify import slugify from sqlalchemy.ext.orderinglist import ordering_list +from sqlalchemy.orm import validates from utils.logger import logger @@ -43,20 +44,26 @@ recipes2tags = sa.Table( class Category(SqlAlchemyBase): __tablename__ = "categories" id = sa.Column(sa.Integer, primary_key=True) - name = sa.Column(sa.String, index=True) - slug = sa.Column(sa.String, index=True, unique=True) + name = sa.Column(sa.String, index=True, nullable=False) + slug = sa.Column(sa.String, index=True, unique=True, nullable=False) recipes = orm.relationship( "RecipeModel", secondary=recipes2categories, back_populates="categories" ) + @validates("name") + def validate_name(self, key, name): + assert not name == "" + return name + def __init__(self, name) -> None: self.name = name.strip() self.slug = slugify(name) @staticmethod def create_if_not_exist(session, name: str = None): + test_slug = slugify(name) try: - result = session.query(Category).filter(Category.name == name.strip()).one() + result = session.query(Category).filter(Category.slug == test_slug).one() if result: logger.info("Category exists, associating recipe") return result @@ -82,12 +89,17 @@ class Category(SqlAlchemyBase): class Tag(SqlAlchemyBase): __tablename__ = "tags" id = sa.Column(sa.Integer, primary_key=True) - name = sa.Column(sa.String, index=True) - slug = sa.Column(sa.String, index=True, unique=True) + name = sa.Column(sa.String, index=True, nullable=False) + slug = sa.Column(sa.String, index=True, unique=True, nullable=False) recipes = orm.relationship( "RecipeModel", secondary=recipes2tags, back_populates="tags" ) + @validates("name") + def validate_name(self, key, name): + assert not name == "" + return name + def to_str(self): return self.name @@ -105,8 +117,9 @@ class Tag(SqlAlchemyBase): @staticmethod def create_if_not_exist(session, name: str = None): + test_slug = slugify(name) try: - result = session.query(Tag).filter(Tag.name == name.strip()).first() + result = session.query(Tag).filter(Tag.slug == test_slug).first() if result: logger.info("Tag exists, associating recipe") @@ -169,7 +182,7 @@ class RecipeModel(SqlAlchemyBase, BaseMixins): id = sa.Column(sa.Integer, primary_key=True) # General Recipe Properties - name = sa.Column(sa.String) + name = sa.Column(sa.String, nullable=False) description = sa.Column(sa.String) image = sa.Column(sa.String) recipeYield = sa.Column(sa.String) @@ -205,6 +218,11 @@ class RecipeModel(SqlAlchemyBase, BaseMixins): orgURL = sa.Column(sa.String) extras: List[ApiExtras] = orm.relationship("ApiExtras", cascade="all, delete") + @validates("name") + def validate_name(self, key, name): + assert not name == "" + return name + def __init__( self, session, diff --git a/mealie/services/backups/imports.py b/mealie/services/backups/imports.py index 2f970c294..9e5ca7c83 100644 --- a/mealie/services/backups/imports.py +++ b/mealie/services/backups/imports.py @@ -95,9 +95,24 @@ class ImportDatabase: del recipe_dict["_id"] del recipe_dict["dateAdded"] except: - logger.info("Detected new backup Schema, skipping migration...") - return recipe_dict + pass # Migration from list to Object Type Data + try: + if "" in recipe_dict["tags"]: + recipe_dict["tags"] = [ + tag for tag in recipe_dict["tags"] if not tag == "" + ] + except: + pass + + try: + if "" in recipe_dict["categories"]: + recipe_dict["categories"] = [ + cat for cat in recipe_dict["categories"] if not cat == "" + ] + except: + pass + if type(recipe_dict["extras"]) == list: recipe_dict["extras"] = {}