【问题标题】:Name 'Key' not defined Lambda function to access DynamoDB名称“键”未定义用于访问 DynamoDB 的 Lambda 函数
【发布时间】:2018-08-30 16:03:14
【问题描述】:

我在 Python 中使用 boto3 库中的查询函数并收到以下错误:

name 'Key' is not defined: NameError
Traceback (most recent call last):
File "/var/task/lambda_function.py", line 51, in lambda_handler
if not getAssetExistance(slack_userID):
File "/var/task/lambda_function.py", line 23, in getAssetExistance
response = dynamoTable.query(KeyConditionExpression=Key('userID').eq(asset))
NameError: name 'Key' is not defined

我一直在阅读一堆关于通过 Lambda 访问 DynamoDB 的教程,并且在尝试是否存在键时,它们都使用这个 KeyConditionExpression 行。

这里是相关代码(第23行是查询行):

def getAssetExistance(asset):
    dynamoTable = dynamo.Table('Assets')
    response    = dynamoTable.query(KeyConditionExpression=Key('userID').eq(asset))

    return bool(response)

我基本上想检查我的 DynamoDB 表中的主分区键(这是一个松弛的用户 ID)并查看是否存在。

如果相关,这里是其余代码:

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

import boto3
import logging
import os
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.resource('dynamodb', region_name=REGION_NAME, endpoint_url="https://dynamodb.us-east-1.amazonaws.com")

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

def getAssetExistance(asset):
    dynamoTable = dynamo.Table('Assets')
    response    = dynamoTable.query(KeyConditionExpression=Key('userID').eq(asset))

    return bool(response)

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_userID   = slack_event["user"]
    slack_text     = slack_event["text"]
    channel_id     = slack_event["channel"]
    slack_reply    = ""

    # Ignore bot messages.
    if "bot_id" in slack_event:
        slack_reply = ""
    else:

        # Start data sift.
        if slack_text.startswith("!networth"):
            slack_reply = "Your networth is: "
        elif slack_text.startswith("!price"):
            command,asset = text.split()
            slack_reply = "The price of a(n) %s is: " % (asset)
        elif slack_text.startswith("!addme"):
            if not getAssetExistance(slack_userID):
                slack_reply = "Adding user: %s" % (slack_userID)
                dynamo.update_item(TableName=ASSET_TABLE, 
                    Key={'userID':{'S':'slack_userID'}},
                    AttributeUpdates= {
                        'resources':{
                            'Action': 'ADD',
                            'Value': {'N': '1000'}
                        }
                    }
                )
            else:
                slack_reply = "User %s already exists" % (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"

我的 DynamoDB 表名为“Assets”,并且有一个名为“userID”(字符串)的主分区键。

我对这一切肯定还是个新手,所以不要害怕称我为傻瓜。任何和所有的帮助表示赞赏。此代码的目标是检查用户是否作为键存在于 DynamoDB 中,如果不存在,则将其添加到表中。

【问题讨论】:

    标签: python-3.x aws-lambda amazon-dynamodb slack-api


    【解决方案1】:

    你需要导入Key函数,像这样:

    from boto3.dynamodb.conditions import Key
    

    【讨论】:

    • 导入boto3不会带来所有的功能/条件吗?还是我误会了什么?
    • @slnd54 我想你可能已经在问这个问题的那段时间里意识到了答案,但是 Saigets 的回答在下面暗示了解释。导入模块时,您可以访问所有变量/函数/等,但它们保留自己的命名空间。您必须使用 from __ import __ 样式语法将变量的名称直接放入代码的命名空间中。
    【解决方案2】:

    无需第二次导入,您可以像这样处理它: boto3.dynamodb.conditions.Key

    def getAssetExistance(asset):
    dynamoTable = dynamo.Table('Assets')
    response    = dynamoTable.query(KeyConditionExpression= boto3.dynamodb.conditions.Key('userID').eq(asset))
    
    return bool(response)
    

    【讨论】:

      【解决方案3】:

      编写以下代码从 dynamo db 获取数据并得到错误 'NameError: name 'Key' is not defined'。

      我必须通过导入'from boto3.dynamodb.conditions import Key'来修复它

                  response = dynamo_table.query(KeyConditionExpression=Key(val).eq(str(key_dictionary[val])))
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2020-09-01
        • 1970-01-01
        • 2018-11-02
        • 1970-01-01
        • 2013-11-14
        • 1970-01-01
        • 2021-07-09
        • 2021-07-07
        相关资源
        最近更新 更多