【问题标题】:SQLAlchemy delete all entries of many to many relationshipSQLAlchemy 删除多对多关系的所有条目
【发布时间】:2021-05-16 14:25:49
【问题描述】:

所以我有一个记录食谱的程序。一个食谱有许多成分,它们有多对多的关系。有一个成分表,它们通过 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")

配方成分:

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")

【问题讨论】:

  • 请参阅Proxying to Dictionary Based Collections,这可能会帮助您简化 n-m 关系的使用。
  • 至于删除:首先删除所有应该解决它,但它可能不是最有效的数据库操作和保留审计/历史记录(如果你需要这样的事情)。因此,您可能希望将例程拆分为 3 个部分:1. 更新现有数量,2. 删除尚未找到的数量,以及 3. 添加新成分。

标签: python-3.x sqlalchemy


【解决方案1】:

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

我加了: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"}

【讨论】:

  • 您不需要明确删除旧的成分;只需替换它们like this
猜你喜欢
  • 1970-01-01
  • 2016-04-12
  • 1970-01-01
  • 2018-02-02
  • 2021-10-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-05-03
相关资源
最近更新 更多