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

无法覆盖DynamoDB M类型值,删除该属性时遇RequestAbortedError

问题分析与解决方案

你遇到的问题根源在于对DynamoDB的M类型(映射类型)更新规则理解有误,同时代码中存在几处逻辑/语法错误,最终导致请求异常。


一、M类型字段的合法更新方式

DynamoDB的M类型要求必须是键值对组成的合法映射结构,不能直接赋值空字符串。要处理M类型字段,有两种合规操作:

  • 保留字段但清空内容:将其设为空映射 {M: {}}
  • 直接删除字段:使用REMOVE操作符移除该属性

二、你的代码存在的关键问题

  1. Key参数格式错误:Key: {'recipe_index': data} 中data未定义,且未指定DynamoDB数据类型(如字符串类型需写为{S: data}),导致无法定位目标条目。
  2. 类型捕获逻辑不一致:当ntNodes.length <=1时,返回的是字符串数组而非{S: 值}的对象数组,导致nutrientsMap的键格式不合法,触发请求校验失败。
  3. 未阻止表单默认行为:表单提交会默认刷新页面,直接中断DynamoDB请求,这是RequestAbortedError的常见诱因。

三、修正后的代码示例

function checkInputs(event) {
    if (event) {
        return event.value;
    } else {
        return '';
    }
}

export const EditRecipe = () => {
    // 假设recipe_index的值已提前获取(比如从组件状态/Props中)
    const recipeIndex = "your-target-recipe-id";

    function HandleSubmit(event) {
        event.preventDefault(); // 阻止页面刷新,避免请求中断

        const AWS = require('aws-sdk');
        const ddb = new AWS.DynamoDB({ apiVersion: '2012-08-10' });

        // 处理营养值
        const nvNodes = event.target.nutrientsValue;
        const currentNutrientsValue = nvNodes.length > 1
            ? Array.prototype.map.call(nvNodes, t => ({ S: t.value }))
            : [{ S: checkInputs(nvNodes) }];

        // 处理营养类型 - 统一返回{S: 值}结构,修正原逻辑的不一致
        const ntNodes = event.target.nutrientsType;
        const currentNutrientsType = ntNodes.length > 1
            ? Array.prototype.map.call(ntNodes, t => ({ S: t.value }))
            : [{ S: checkInputs(ntNodes) }];

        // 构建合法的M类型映射
        const nutrientsMap = {};
        currentNutrientsType.forEach((keyObj, i) => {
            const keyName = keyObj.S;
            nutrientsMap[keyName] = currentNutrientsValue[i];
        });

        // 方案1:清空nutrients字段(保留字段,设为空映射)
        const updateParams = {
            TableName: 'recipes',
            Key: { 'recipe_index': { S: recipeIndex } }, // 明确指定数据类型
            UpdateExpression: 'SET nutrients = :nutrients',
            ExpressionAttributeValues: {
                ':nutrients': { M: nutrientsMap } // 若nutrientsMap为空,则生成空映射
            },
        };

        // 方案2:直接删除nutrients字段(不需要保留字段时用)
        // const updateParams = {
        //     TableName: 'recipes',
        //     Key: { 'recipe_index': { S: recipeIndex } },
        //     UpdateExpression: 'REMOVE nutrients'
        // };

        ddb.updateItem(updateParams, (err, data) => {
            err ? console.log("Error", err) : console.log("Success", data);
        });
    }

    return (
        <form onSubmit={HandleSubmit} method="post">
            <Nutrients tableName='recipes' title={title} edit={true}/>
            <input value='Save' type="submit"/> 
        </form>
    );
};

补充提示

  • 确保Key中的每个属性都明确指定DynamoDB数据类型(如数字用{N: "123"},字符串用{S: "xxx"})。
  • 若要将M类型字段设为空,只需保证nutrientsMap是空对象,此时:nutrients会被解析为{M: {}},符合DynamoDB的类型要求。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.06 02:10:39