在DynamoDB python boto3中执行update_item时出错

问题描述 投票:2回答:1

我在DynamoDB中有一个表,它为我提供了大量文档。这些文档包含以下字段:computedID(主分区键),publication_timestamp,displayTitle,displayText,displayUrl,producer和tags。

我想在表上执行update_item,以便只有在publication_timestamp,displayTitle,displayText,displayUrl,producer和tags中的任何字段发生更改时才会更新记录。如果记录是全新的,它将被简单地插入表中。

问题是表中的所有现有文档或传入文档都没有displayTitle,displayText,displayUrl和tags。他们可能会错过任何数量的这些领域。

我尝试过以下方法:

dynamodb = boto3.resource('dynamodb')
table = dynamodb.Table('project_Incoming_Data')
print("Sending documents to DynamoDB...")

for item in Docs:
    try:
        response=table.update_item(
            Key={"computedID":item["computedID"]},
            UpdateExpression="SET publication_timestamp = :time, displayTitle= :title, displayText= :text, producer = :p, tags= :tags, displayUrl= :url, time_to_live= :ttl",
            ConditionExpression= "publication_timestamp <> :time OR (attribute_exists(displayTitle) AND displayTitle <> :title) OR (attribute_exists(displayText) AND displayText <> :text) OR producer <> :p OR (attribute_exists(tags) AND tags <> :tags) OR (attribute_exists(displayUrl) AND displayUrl <> :url)",
            ExpressionAttributeValues={
                    ":time":item["publication_timestamp"],
                    ":ttl":item["time_to_live"],
                    ":title":item["displayTitle"],
                    ":text":item["displayText"],
                    ":p":item["producer"],
                    ":tags":item["tags"],
                    ":url":item["displayUrl"]
            },
            ReturnValues="UPDATED_NEW"
            )
        print("response is: "+str(response))
    except Exception as e:
        print (e)
print("Done with sending documents to DynamoDB")

我仍然无法将我的一些文档存入DynamoDB。我得到的错误是'displayText'!我猜我确保记录中存在该字段的机制对于没有该字段的文档不起作用。

知道如何解决这个问题吗?

python amazon-dynamodb boto3
1个回答
2
投票

我找到了解决方案!问题是,即使文档可能遗漏任何displayText,displayTitle,tags或displayUrl字段,UpdateExpression,ConditionExpression和ExpressionAttributeValues中的所有三个仍在考虑文档的那些字段。解决方案是根据文档中的字段分别为每个文档构建它们。

def send_docs_to_DynamoDB(Docs):
    dynamodb = boto3.resource('dynamodb')
    table = dynamodb.Table('Compete_Dental_Incoming_Data')
    print("Sending documents to DynamoDB...")

    for item in Docs:
            expression_attribute_values={
                    ":time":item["publication_timestamp"],
                    ":ttl":item["time_to_live"],
                    ":p":item["producer"]
            }
            update_expression="SET publication_timestamp = :time, producer = :p, time_to_live= if_not_exists(time_to_live, :ttl)"
            condition_expression= "publication_timestamp <> :time OR producer <> :p"
            try:
                    if 'displayTitle' in item.keys():
                            update_expression+=", displayTitle= :title"
                            expression_attribute_values[":title"]=item["displayTitle"]
                            condition_expression+=" OR displayTitle <> :title"
                    if 'displayText' in item.keys():
                            update_expression+=", displayText= :text"
                            expression_attribute_values[":text"]=item["displayText"]
                            condition_expression+=" OR displayText <> :text"
                    if 'displayUrl' in item.keys():
                            update_expression+=", displayUrl= :url"
                            expression_attribute_values[":url"]=item["displayUrl"]
                            condition_expression+=" OR displayUrl <> :url"
                    if 'tags' in item.keys():
                            update_expression+=", tags= :tags"
                            expression_attribute_values[":tags"]=item["tags"]
                            condition_expression+=" OR tags <> :tags"

                    response=table.update_item(
                            Key={"computedID":item["computedID"]},
                            UpdateExpression=update_expression,
                            ConditionExpression= condition_expression,
                            ExpressionAttributeValues=expression_attribute_values,
                            ReturnValues="UPDATED_NEW"
                            )
                    print("response is: "+str(response))
            except Exception as e:
                    print (e)
    print("Done with sending documents to DynamoDB")
© www.soinside.com 2019 - 2024. All rights reserved.