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

DynamoDB BatchWrite不同Hash Key同Range Key为何报重复键错误?

问题原因与解决办法

问题根源

你遇到的报错是因为复用了同一个mainItem map对象。Go语言中的map是引用类型,循环里你只修改了address字段,然后将这个map传入PutRequest.Item,但所有PutRequest保存的都是这个map的引用。当循环结束时,所有Item的address都会被覆盖成最后一次循环的storeKey对应值,导致所有请求的主键变成完全相同的(最后一个address, tx_id),DynamoDB因此检测到重复主键并抛出ValidationException。

解决办法

每次循环都创建独立的Item对象,避免引用复用:

方案1:循环内新建Item(推荐)

如果你的Item除了address还有其他固定字段(比如tx_id),可以在循环内初始化完整的Item:

for _, storeKey := range t.StoreKeys() {
    // 每次循环新建独立的Item map
    mainItem := make(map[string]types.AttributeValue)
    
    // 先赋值固定字段(比如tx_id)
    mainItem["tx_id"], err = dynamodbattribute.Marshal(yourTxIdValue)
    if err != nil {
        return err
    }
    
    // 赋值当前循环的address
    mainItem["address"], err = dynamodbattribute.Marshal(storeKey)
    if err != nil {
        return err
    }
    
    mainTxPut := dynamodb.PutRequest{
        Item: mainItem,
    }

    writeRequests = append(writeRequests, &dynamodb.WriteRequest{
        PutRequest: &mainTxPut,
    })
}

方案2:复制已有Item(适用于原Item有大量固定字段的场景)

如果原mainItem已经包含大部分固定字段,可以在循环内复制一份新的map再修改address:

for _, storeKey := range t.StoreKeys() {
    // 复制原mainItem到新的map,避免引用复用
    newItem := make(map[string]types.AttributeValue)
    for k, v := range mainItem {
        newItem[k] = v
    }
    
    // 修改当前循环的address
    newItem["address"], err = dynamodbattribute.Marshal(storeKey)
    if err != nil {
        return err
    }
    
    mainTxPut := dynamodb.PutRequest{
        Item: newItem,
    }

    writeRequests = append(writeRequests, &dynamodb.WriteRequest{
        PutRequest: &mainTxPut,
    })
}

这样每个PutRequest的Item都是独立的对象,主键会被正确设置为(当前address, tx_id),不会出现重复的情况。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.28 18:32:56