在DynamoDB中执行update_item时出错python boto3

时间:2018-03-01 02:05:38

标签: python amazon-dynamodb boto3

我在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。我得到的错误是&#39; displayText&#39;!我猜测我确保该字段存在于记录中的机制对于没有该字段的文档不起作用。

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

1 个答案:

答案 0 :(得分: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")