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' }); } });
关键细节说明
- 数据类型转换:前端传入的
ingredientId和quantity可能是字符串类型,必须转成Prisma Schema中定义的Int和Float类型,避免类型不匹配错误。 - 拆分处理逻辑:
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
相关产品推荐
相关产品推荐

