Amazon web services DynamoDB BatchWriteItem:提供的项键列表包含重复项

Amazon web services DynamoDB BatchWriteItem:提供的项键列表包含重复项,amazon-web-services,aws-lambda,amazon-dynamodb,Amazon Web Services,Aws Lambda,Amazon Dynamodb,我正在尝试使用DynamoDB操作BatchWriteItem,其中我想在一个表中插入多条记录 此表有一个分区键和一个排序键 我正在使用AWS lambda和Go语言 我得到要插入到切片中的元素 我遵循这个程序 为列表中的第一条记录创建PutRequest结构并添加AttributeValue 我正在从此PutRequest创建WriteRequest 我正在将这个WriteRequest添加到一个WriteRequests数组中 我正在创建BatchWriteItemInput,它由Reque

我正在尝试使用DynamoDB操作
BatchWriteItem
,其中我想在一个表中插入多条记录

此表有一个分区键和一个排序键

我正在使用AWS lambda和Go语言

我得到要插入到切片中的元素

我遵循这个程序

  • 为列表中的第一条记录创建
    PutRequest
    结构并添加AttributeValue

  • 我正在从此
    PutRequest
    创建
    WriteRequest

  • 我正在将这个
    WriteRequest
    添加到一个
    WriteRequests数组中

  • 我正在创建
    BatchWriteItemInput
    ,它由
    RequestItems
    组成,基本上是一个表名映射和
    WriteRequests
    数组

  • 在此之后,我调用了
    BatchWriteItem
    ,这将导致出现一个错误-提供的项键列表包含重复项


    任何指针,为什么会发生这种情况?

    您提供了两个或多个具有相同分区/排序键的项


    根据这些文档,您不能在同一个BatchWriteItem请求中对同一项执行多个操作。

    注意事项:此答案适用于Python

    正如@Benoit所说,boto3文件说明:

    如果希望跳过单个批处理写入请求的无重复限制,请将其作为botocore.exceptions.ClientError:调用BatchWriteItem操作时发生错误(ValidationException):提供的项键列表包含重复项

    根据和,您可以在批处理编写器上指定
    overwrite\u by_pkeys=['partition\u key','sort\u key']
    ,以“如果与指定主键上的新请求项匹配,则消除缓冲区中的重复请求项”。也就是说,如果组合主排序已经存在于缓冲区中,它将删除该请求,并将其替换为新的

    例子 假设有一个dataframe要写入DynamoDB表,下面的函数可能会有所帮助

    import json 
    import datetime as dt 
    import boto3 
    import pandas as pd 
    from typing import Optional
    
    def write_dynamoDB(df:'pandas.core.frame.DataFrame', tbl:str, partition_key:Optional[str]=None, sort_key:Optional[str]=None):
        '''
           Function to write a pandas DataFrame to a DynamoDB Table through 
           batchWrite operation. In case there are any float values it handles 
           them by converting the data to a json format.  
           Arguments: 
           * df: pandas DataFrame to write to DynamoDB table. 
           * tbl: DynamoDB table name. 
           * partition_key (Optional): DynamoDB table partition key. 
           * sort_key (Optional): DynamoDB table sort key. 
        '''
    
        # Initialize AWS Resource 
        dynamodb = boto3.resource('dynamodb')
        table = dynamodb.Table(tbl)
    
        # Check if overwrite keys were provided
        overwrite_keys = [partition_key, sort_key] if partition_key else None
    
        # Check if they are floats (convert to decimals instead) 
        if any([True for v in df.dtypes.values if v=='float64']):
    
            from decimal import Decimal
    
            # Save decimals with JSON
            df_json = json.loads(
                           json.dumps(df.to_dict(orient='records'),
                                      default=date_converter,
                                      allow_nan=True), 
                           parse_float=Decimal
                           )
    
            # Batch write 
            with table.batch_writer(overwrite_by_pkeys=overwrite_keys) as batch: 
                for element in df_json:
                    batch.put_item(
                    Item=element
                )
    
        else: # If there are no floats on data 
    
        # Batch writing 
            with table.batch_writer(overwrite_by_pkeys=overwrite_keys) as batch: 
    
                columns = df.columns
    
                for row in df.itertuples():
                    batch.put_item(
                        Item={
                            col:row[idx+1] for idx,col in enumerate(columns)
                        }
                    )
    
    def date_converter(obj):
        if isinstance(obj, dt.datetime):
            return obj.__str__()
        elif isinstance(obj, dt.date):
            return obj.isoformat()
    

    通过调用
    write\u dynamoDB(数据帧,'my\u table','u partition\u key','u sort\u key')
    使用
    batch\u writer
    而不是
    batch\u write\u item

    import boto3
    
    dynamodb = boto3.resource("dynamodb", region_name='eu-west-1')
    my_table = dynamodb.Table('mirrorfm_yt_tracks')
    
    with my_table.batch_writer(overwrite_by_pkeys=["user_id", "game_id"]) as batch:
        for item in items:
            batch.put_item(
                Item={
                    'user_id': item['user_id'],
                    'game_id': item['game_id'],
                    'score': item['score']
                }
            )
    
    如果没有排序键,
    overwrite\u by_pkeys
    可以是
    None


    这基本上与@MiguelTrejo(谢谢!+1)的答案相同,但简化了

    谢谢,这很有效。Go列表中存在与重复项目相关的问题。使用Bot3,您可以将overwrite_by_pkeys
    用于表格。batch_writer(overwrite_by_pkeys=['pk',sk'])作为batch表格: