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

DynamoDB批量写入报错:提供的键元素与架构不匹配

问题:批量写入DynamoDB时出现ValidationException错误

我尝试将本地JSON文件(AllFlagsOn.json)中的数据批量写入AWS DynamoDB已有表tableName,使用以下TypeScript代码实现:

if (appProps.accountName === 'star') {
    new Stack(app, DEV_APP_NAME);
    jsonFilePath = './bin/AllFlagsOn.json';
    
        const file = fs.readFileSync(jsonFilePath, 'utf-8');
        const data = JSON.parse(file);
        const items = data["ect-feed-status"]; 
        const client = new DynamoDBClient({ region: 'us-east-1'});

        const command = new BatchWriteCommand({
            RequestItems: {
                'tableName': items.map((item: any) => ({
                    PutRequest: {
                        Item: item.PutRequest.Item,

                    },
                })),
            },
        });
        client.send(command).then((response) => {
            console.log("Batch write succeeded: ", response);
        })
        .catch((error) => {
            console.log("Batch write failed: ", error);
        });
}

JSON文件内容如下:

{
    "tableName": [
        {
            "PutRequest": {
                "Item": {
                    "FeatureName": { "S": "blah" },
                    "Active": { "BOOL": true }
                }
            }
        },
        {
            "PutRequest": {
                "Item": {
                    "FeatureName": { "S": "blahablah" },
                    "Active": { "BOOL": true }
                }
            }
        },
        {
            "PutRequest": {
                "Item": {
                    "FeatureName": { "S": "blahblahblah" },
                    "Active": { "BOOL": true }
                }
            }
        }
    ]
}

执行后收到错误:

Batch write failed:  ValidationException: The provided key element does not match the schema

JSON.stringify(command)输出如下:

{"middlewareStack":{},"input":{"RequestItems":{"tableName":[{"PutRequest":{"Item":{"FeatureName":{"S":"blah"},"Active":{"BOOL":true}}}},{"PutRequest":{"Item":{"FeatureName":{"S":"blahblah"},"Active":{"BOOL":true}}}},{"PutRequest":{"Item":{"FeatureName":{"S":"blahblahblah"},"Active":{"BOOL":true}}}}]}},"inputKeyNodes":[{"key":"RequestItems","children":{"children":[{"key":"PutRequest","children":[{"key":"Item"}]},{"key":"DeleteRequest","children":[{"key":"Key"}]}]}}],"outputKeyNodes":[{"key":"UnprocessedItems","children":{"children":[{"key":"PutRequest","children":[{"key":"Item"}]},{"key":"DeleteRequest","children":[{"key":"Key"}]}]}},{"key":"ItemCollectionMetrics","children":{"children":[{"key":"ItemCollectionKey"}]}}],"clientCommand":{"middlewareStack":{},"input":{"RequestItems":{"tableName":[{"PutRequest":{"Item":{"FeatureName":{"M":{"S":{"S":"blah"}}},"Active":{"M":{"BOOL":{"BOOL":true}}}}}},{"PutRequest":{"Item":{"FeatureName":{"M":{"S":{"S":"blahblah"}}},"Active":{"M":{"BOOL":{"BOOL":true}}}}}},{"PutRequest":{"Item":{"FeatureName":{"M":{"S":{"S":"blahblahblah"}}},"Active":{"M":{"BOOL":{"BOOL":true}}}}}]}}}}

表结构描述(Describe Table)输出:

{
"Table": {
    "AttributeDefinitions": [
        {
            "AttributeName": "FeatureName",
            "AttributeType": "S"
        }
    ],
    "TableName": "tableName",
    "KeySchema": [
        {
            "AttributeName": "FeatureName",
            "KeyType": "HASH"
        }
    ],
    "TableStatus": "ACTIVE",
    "CreationDateTime": "2022-08-01T15:24:38.112000-05:00",
    "ProvisionedThroughput": {
        "NumberOfDecreasesToday": 0,
        "ReadCapacityUnits": 1,
        "WriteCapacityUnits": 1
    },
    "TableSizeBytes": 105,
    "ItemCount": 3,
    "TableArn": "arn:aws:dynamodb:us-east-1:blahablahg",
    "TableId": "ididididid",
    "DeletionProtectionEnabled": false
}
}

我已核对属性名和数据类型均与表结构匹配,请问问题出在哪里?


解答

问题出在两处:

  1. JSON数据读取不匹配:代码中读取data["ect-feed-status"],但JSON文件的顶级键是tableName,这会导致items无法正确获取数据,必须把这行改为const items = data["tableName"]。

  2. SDK格式兼容错误:你的JSON文件使用了DynamoDB原生类型格式(带{S: "xxx"}这类标识),但AWS SDK for JavaScript v3的BatchWriteCommand默认期望使用简化的JS原生类型,SDK会自动完成类型映射。从command的序列化输出能看到数据被错误嵌套:

    "FeatureName":{"M":{"S":{"S":"blah"}}}
    

    说明SDK把你原本的类型标识对象当成了普通Map类型处理,导致结构完全不符合表的键架构。

修复方案

方案一:用SDK工具转换格式

引入marshall函数将原生格式数据转换为SDK兼容结构:

import { marshall } from "@aws-sdk/util-dynamodb";

// 其余代码不变
const command = new BatchWriteCommand({
    RequestItems: {
        'tableName': items.map((item: any) => ({
            PutRequest: {
                Item: marshall(item.PutRequest.Item), // 添加marshall转换
            },
        })),
    },
});

方案二:修改JSON为简化格式

去掉JSON中的类型标识,直接使用JS原生类型:

{
    "tableName": [
        {
            "PutRequest": {
                "Item": {
                    "FeatureName": "blah",
                    "Active": true
                }
            }
        },
        // 其余条目同理修改
    ]
}

修改后代码无需额外转换,SDK会自动处理类型映射。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.18 02:37:12