我在DynamoDB中有一个表,可以为我保存一堆文件。这些文档具有以下字段:computeID(主分区键),publication_timestamp,displayTitle,displayText,displayUrl,生产者和标签。

我想在表上执行update_item,以便仅在任何字段publication_timestamp,displayTitle,displayText,displayUrl,生产者和标签已更改的情况下才更新记录。如果记录是全新记录,则将其简单地插入表中。

问题在于,并非表中的所有现有文档或传入的文档都具有displayTitle,displayText,displayUrl和标记。他们可能会错过任何数量的这些字段。

我尝试了以下方法:

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,tag或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")

关于python - 在DynamoDB python boto3中执行update_item时出错,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/49041524/

10-11 14:25