SQLAlchemy 删除多对多关系的所有条目

时间:2021-05-16 14:25:49

标签: python-3.x sqlalchemy

所以我有一个记录食谱的程序。一个食谱有多种成分,它们之间存在多对多的关系。有一个成分表,它们通过 recipe_ingredients 表链接到一个食谱。

我编写了以下代码来更新食谱(假设我删除了所有成分并添加了一个新成分),但是,它并没有清除旧成分,而是附加所有内容。我在这里做错了吗?

更新配方代码:

@app.route('/recipe', methods=['POST'])
@expects_json(recipeSchema)
def updateRecipe():
    recipeToUpdate = session.query(classes.Recipe).filter(classes.Recipe.id==flask.request.json["id"]).first()
    if recipeToUpdate is not None:
        newRecipe = flask.request.json
        if "name" in newRecipe.keys():
            recipeToUpdate.name = newRecipe["name"]
        if "amountofpeople" in newRecipe.keys():
            recipeToUpdate.amountofpeople = newRecipe["amountofpeople"]
        if "ingredients" in newRecipe.keys():
            newIngredientsArray = []
            for ingredient in newRecipe["ingredients"]:
                if "id" in ingredient.keys():
                    newIngredient = session.query(classes.Ingredient).filter(classes.Ingredient.id==ingredient["id"]).first()
                    newRecipeIngredient = classes.RecipeIngredients(recipe_id=recipeToUpdate.id, ingredient_id=newIngredient.id, ingredient_amount=1)
                    if "ingredient_amount" in ingredient.keys():
                        newRecipeIngredient.ingredient_amount = ingredient["ingredient_amount"]
                    newIngredientsArray.append(newRecipeIngredient)
            recipeToUpdate.ingredients[:] = newIngredientsArray
        session.commit()
        return mapRecipes(recipeToUpdate)
    else:
        return {"id": id, "Error": "Not found"}

食谱:

class Recipe(Base):
    __tablename__ = 'recipes'

    id = Column(Integer, Sequence('recipe_id_seq'), primary_key=True, autoincrement=True)
    amountofpeople = Column(Integer)
    name = Column(String)
    ingredients = relationship("RecipeIngredients", back_populates="recipe")

成分:

class Ingredient(Base):
    __tablename__ = 'ingredients'

    id = Column(Integer, primary_key=True)
    name = Column(String)
    amount = Column(Integer)
    unit = Column(Enum(Units))
    recipe = relationship('RecipeIngredients', back_populates="ingredient")

Recipe_ingredients:

class RecipeIngredients(Base):
    __tablename__ = 'recipe_ingredients'

    id = Column(Integer, primary_key=True)
    recipe_id = Column(Integer, ForeignKey('recipes.id'))
    ingredient_id = Column(Integer, ForeignKey('ingredients.id'))
    ingredient_amount = Column(Integer)
    recipe = relationship('Recipe', back_populates="ingredients")
    ingredient = relationship('Ingredient', back_populates="recipe")

1 个答案:

答案 0 :(得分:0)

我找到了一个解决方案,但我不确定它是否正确:

我添加了:session.query(classes.RecipeIngredients).filter(classes.RecipeIngredients.recipe_id==recipeToUpdate.id).delete() 这将首先删除所有以前的关系,然后再建立新的关系。但我想知道在类中定义同步是否有更简洁的方法。

@app.route('/recipe', methods=['POST'])
@expects_json(recipeSchema)
def updateRecipe():
    recipeToUpdate = session.query(classes.Recipe).filter(classes.Recipe.id==flask.request.json["id"]).first()
    if recipeToUpdate is not None:
        newRecipe = flask.request.json
        if "name" in newRecipe.keys():
            recipeToUpdate.name = newRecipe["name"]
        if "amountofpeople" in newRecipe.keys():
            recipeToUpdate.amountofpeople = newRecipe["amountofpeople"]
        if "ingredients" in newRecipe.keys():
            session.query(classes.RecipeIngredients).filter(classes.RecipeIngredients.recipe_id==recipeToUpdate.id).delete()
            newIngredientsArray = []
            for ingredient in newRecipe["ingredients"]:
                if "id" in ingredient.keys():
                    newIngredient = session.query(classes.Ingredient).filter(classes.Ingredient.id==ingredient["id"]).first()
                    newRecipeIngredient = classes.RecipeIngredients(recipe_id=recipeToUpdate.id, ingredient_id=newIngredient.id, ingredient_amount=1)
                    if "ingredient_amount" in ingredient.keys():
                        newRecipeIngredient.ingredient_amount = ingredient["ingredient_amount"]
                    newIngredientsArray.append(newRecipeIngredient)
            recipeToUpdate.ingredients[:] = newIngredientsArray
        session.commit()
        return mapRecipes(recipeToUpdate)
    else:
        return {"id": id, "Error": "Not found"}
相关问题