在DynamoDB python boto3中执行update_item时出错

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了在DynamoDB python boto3中执行update_item时出错相关的知识,希望对你有一定的参考价值。

我在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'!我猜我确保记录中存在该字段的机制对于没有该字段的文档不起作用。

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

答案

我找到了解决方案!问题是,即使文档可能遗漏任何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")

以上是关于在DynamoDB python boto3中执行update_item时出错的主要内容,如果未能解决你的问题,请参考以下文章

无法使用Lambda Python 3.6 Boto3在现有DynamoDB表中放置新项目[关闭]

Python Boto3 - 数据未正确写入DynamoDB

如何将Python Boto3中的DynamoDB扫描格式化为可人读的html?

使用带有全局二级索引的 boto3 在 dynamodb 上进行有条件的放置

用于 DynamoDB 查询的 Python 代码适用于 v3.6,但不适用于 python 2.7

json Boto3 DynamoDB更新响应