You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Prisma MySQL后端更新Recipe时Upsert无Where参数报错求助

解决Recipe更新时Recipe_Ingredient的更新与创建问题

问题根源:使用upsert操作时,每个子项必须提供有效的where条件,新添加的Recipe_Ingredient因为没有数据库生成的id,导致where参数为undefined,触发Prisma的验证错误。

直接修改API代码,将已有配料(带id)和新配料(无id)分开处理,分别用update和create操作:

app.put('/api/recipes/:id', async (req, res) => {
    console.log(req.body);
    try {
      const recipeId = Number(req.params.id);
      const {
        name,
        description,
        steps,
        notes,
        Recipe_Ingredient,
      } = req.body;

      // 拆分已有配料(带id)和新配料(无id)
      const existingIngredients = Recipe_Ingredient.filter(ing => ing.id);
      const newIngredients = Recipe_Ingredient.filter(ing => !ing.id);

      const updatedRecipe = await prisma.recipe.update({
        where: {
          id: recipeId,
        },
        data: {
          name: name,
          description: description,
          steps: steps,
          notes: notes,
          Recipe_Ingredient: {
            // 更新已有配料
            update: existingIngredients.map(ingredient => ({
              where: { id: ingredient.id },
              data: {
                ingredientId: Number(ingredient.ingredientId),
                quantity: parseFloat(ingredient.quantity),
                measurement: ingredient.measurement,
              },
            })),
            // 创建新配料
            create: newIngredients.map(ingredient => ({
              ingredientId: Number(ingredient.ingredientId),
              quantity: parseFloat(ingredient.quantity),
              measurement: ingredient.measurement,
            })),
          },
        },
        include: {
          Recipe_Ingredient: true,
        },
      });

      res.status(200).json(updatedRecipe);
    } catch (error) {
      console.error(error);
      res.status(500).json({ error: 'Failed to update recipe' });
    }
  });

关键细节说明

  1. 数据类型转换:前端传入的ingredientId和quantity可能是字符串类型,必须转成Prisma Schema中定义的Int和Float类型,避免类型不匹配错误。
  2. 拆分处理逻辑:
    • update数组只处理带有id的已有配料,每个子项都提供有效的where条件(基于配料id)
    • create数组处理无id的新配料,直接传入创建所需字段即可,不需要where条件

可选扩展:删除未传入的配料

如果需要同步删除前端已移除的配料,可以在Recipe_Ingredient操作中添加deleteMany,删除不在传入列表中的配料:

Recipe_Ingredient: {
  update: existingIngredients.map(...),
  create: newIngredients.map(...),
  // 删除不在传入列表中的配料
  deleteMany: {
    id: {
      notIn: existingIngredients.map(ing => ing.id),
    },
  },
}

内容的提问来源于stack exchange,提问作者Felauras

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.15 15:15:54