使用 Python 通过 Lambda 访问 DynamoDB 而不会达到 read/write 容量

Accessing DynamoDB through Lambda with Python without hitting read/write capacity

出于某种原因,每次我 运行 我的 Lambda 函数都会收到来自 DynamoDB 的错误:

INSUFFICIENT_DATA     Assets-ReadCapacityUnitsLimit-BasicAlarm
ConsumedReadCapacityUnits >= 240 for 5 datapoints within 5 minutes

我对 AWS 和 Python 的一切都是新手,所以希望有人能看一眼这段代码并指出我的愚蠢之处。

我想做的是使用 slack 中的“!Addme”命令将用户添加到数据库中。我已经设法让 slack 和 lambda 以发送命令和接收答案的形式相互交谈。对于我的下一步,我想学习如何让 Lambda 从 dynamoDB 中提取数据。

从我的警报来看,我每秒发出的 read/write 请求似乎太多了。这可能只是我缺乏 python 理解。所以我的问题是,在我定义的函数(getAssetTableIDList() 和 getUserIDExistance(userID))上,我在做一些愚蠢的事情吗?

感谢所有帮助。谢谢

我的 DynamoDB 的基本信息: 密钥 = 用户 ID(字符串) Read/Write容量=1

################################
# Slack Lambda handler.
################################

import boto3
import os
import logging
import urllib

# Grab data from the environment.
BOT_TOKEN   = os.environ["BOT_TOKEN"]
ASSET_TABLE = os.environ["ASSET_TABLE"]
REGION_NAME = os.getenv('REGION_NAME', 'us-east-1')

dynamo = boto3.client('dynamodb', region_name=REGION_NAME, endpoint_url="http://localhost:8000")

# Define the URL of the targeted Slack API resource.
SLACK_URL = "https://slack.com/api/chat.postMessage"

def getAssetTableIDList():
    tables = dynamo.scan(TableName=ASSET_TABLE)

    userIDList = {}
    for item in tables['Items']:
        userList[item['userID']['S']]

    return userIDList 

def getUserIDExistance(userID):
    userIDList = getAssetTableIDList()

    if userID in userIDList:
        userIDExist = true

    return userIDExist 

def lambda_handler(data, context):
    # Slack challenge answer.
    if "challenge" in data:
        return data["challenge"]

    # Grab the Slack channel data.
    slack_event  = data['event']
    slack_user   = slack_event["user"]
    slack_text   = slack_event["text"]
    channel_id   = slack_event["channel"]
    slack_userID = slack_user["ID"]
    slack_reply  = ""

    # Ignore bot messages.
    if "bot_id" in slack_event:
        logging.warn("Ignore bot event")
    else:

        # Start data sift.
        if slack_text.startswith("!networth"):
            slack_reply = "Your networth is: "
        elif slack_text.startwith("!price"):
            command,asset = text.split()
            slack_reply = "The price of a(n) %s is: " % (asset)
        elif slack_text.startwith("!Addme"):
            if not getUserIDExistance(slack_userID):
                slack_reply = "Added user: %s" % (slack_user)
                dynamo.update_item(TableName=ASSET_TABLE, 
                    Key={'userID':{'S':'slack_userID'},
                    AttributeUpdates= {
                        'resources':{
                            'Action': 'ADD',
                            'Value': {'N': '1000'}
                        }
                    }
                )
            else
                slack_reply = "User %s(%s) already exists" % (slack_user, slack_userID)

        # We need to send back three pieces of information:
        data = urllib.parse.urlencode(
            (
                ("token", BOT_TOKEN),
                ("channel", channel_id),
                ("text", slack_reply)
            )
        )
        data = data.encode("ascii")

        # Construct the HTTP request that will be sent to the Slack API.
        request = urllib.request.Request(
            SLACK_URL, 
            data=data, 
            method="POST"
        )
        # Add a header mentioning that the text is URL-encoded.
        request.add_header(
            "Content-Type", 
            "application/x-www-form-urlencoded"
        )

        # Fire off the request!
        urllib.request.urlopen(request).read()

    # Everything went fine.
    return "200 OK"

您正在执行完整 table 扫描以将整个 table 加载到内存中,然后遍历 table 中的每个对象以查看是否存在条目。您不需要进行扫描,而是需要使用相关 ID 进行查询,然后让 DynamoDB 告诉您该项目是否存在。