簡體   English   中英

dynamodb 表更新項目未檢測到屬性

[英]dynamodb table update item not detecting attribute

更新 dynamodb 表時出現此錯誤:

ERROR:root:------- here: An error occurred (ValidationException) when calling the 
 UpdateItem operation: The provided expression refers to an attribute that does not exist 
 in the item

我認為是 update_vote function 中的表達式引起了麻煩

#!/usr/bin/env python3

import boto3
import json
import logging
import sys

logging.basicConfig(stream=sys.stdout, level=logging.INFO)

queue = boto3.resource('sqs', region_name='us-east-1').get_queue_by_name(QueueName="erjan")
table = boto3.resource('dynamodb', region_name='us-east-1').Table('Votes')

def process_message(message):
    try:
        
        payload = message.message_attributes
        voter = payload['voter']['StringValue']
        vote  = payload['vote']['StringValue']

        logging.info("Voter: %s, Vote: %s", voter, vote)
        store_vote(voter, vote)
        update_count(vote)
        message.delete()
    except Exception as e:
        print('-------')
        print('message.attr')
        print(message.message_attributes)
        try:
            vote = payload['vote']['StringValue']
            logging.error("Failed to process message")
            logging.error('vote %d' % vote)
        except TypeError:           
            logging.error("yes error catched")

def store_vote(voter, vote):
    try:
        logging.info('table put item.......')
        print('table put item......')
        response = table.put_item(
           Item={'voter': voter, 'vote': vote}
        )
    except:
        logging.error(" Failed to store message")
        raise


#this function causes error i think

def update_count(vote):
    logging.info('update count....')
    print('update count....')
    table.update_item(
        Key={'voter': 'default_voter'},
        UpdateExpression="set #vote = #vote + :incr", #this update expression
            ExpressionAttributeNames={'#vote': vote},
            ExpressionAttributeValues={':incr': 1}
    )

if __name__ == "__main__":
    while True:
        try:
            messages = queue.receive_messages(MessageAttributeNames=['vote','voter'])
        except KeyboardInterrupt:
           logging.info("Stopping...")
           break
        except:
            logging.error(sys.exc_info()[0])
            continue
        for message in messages:
            process_message(message)

dynamodb 表有 1 個分區鍵 - 'voter'。 它應該存儲“a”或“b”收到的點擊次數。

如果當前沒有存儲要遞增的值,您可能需要設置一個默認值:

def update_count(vote):
    logging.info('update count....')
    print('update count....')
    table.update_item(
        Key={'voter': 'default_voter'},
        UpdateExpression="set #vote = if_not_exists(#vote, :start) + :incr",  
        ExpressionAttributeNames={'#vote': vote},
        ExpressionAttributeValues={':incr': 1, ':start': 0}
    )

注意if_not_exists會將投票的初始值設置為 0。

您看到此異常的原因是您的項目當前不存在vote屬性,從而導致異常:

提供的表達式引用了項中不存在的屬性


1. 使用ADD而不是SET

這是推薦的方法。 如果該值不存在,它會自動將其設置為 0,然后添加您提供的值。 您唯一會使用選項 #2 的情況是當屬性存儲在嵌套值中時, ADD對此不起作用。

在更新表達式中使用 ADD 操作將新屬性及其值添加到項目中。 文檔

  • ADD path value
table.update_item(
    Key={'voter': 'default_voter'},
    UpdateExpression="ADD #vote :incr",
    ExpressionAttributeNames={'#vote': vote},
    ExpressionAttributeValues={':incr': 1}
)

2.使用if_not_exists Function

如果項目不包含指定路徑的屬性,則 if_not_exists 的計算結果為 value; 否則,它計算為路徑。

這種方法要求您設置一個值,如果該屬性不應存在,則該值最初設置為: :empty=0 與建議您在 DynamoDB 中添加值的方式相比,這更像是一種解決方法。

  • if_not_exists (path, value)
table.update_item(
    Key={'voter': 'default_voter'},
    UpdateExpression="set #vote = if_not_exists(#vote, :empty) + :incr",
    ExpressionAttributeNames={'#vote': vote},
    ExpressionAttributeValues={':incr': 1, ':empty': 0}
)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM