AWS CDK WorkShop [错误] ParamValidationError:参数验证失败:输入中缺少必需参数:“Key”

问题描述 投票:0回答:1

我正在尝试通过 AWS CDK Python Workshop 来提高自己的技能,我按照 WorkShop Guide 中的说明编写了以下代码,但在创建 DynamoDB 表的条目时卡住了。

AWS CDK 研讨会指南链接

https://catalog.us-east-1.prod.workshops.aws/workshops/10141411-0192-4021-afa8-2436f3c66bd8/en-US/3000-python-workshop/400-hit-counter/430-资源

代码

hitcount.py文件中的代码

import json
import os

import boto3

ddb = boto3.resource("dynamodb")
table = ddb.Table(os.environ["HITS_TABLE_NAME"])
_lambda = boto3.client("lambda")

def handler(event, context):
    print("request : {}".format(json.dumps(event)))
    table.update_item(
        key = {"path": event["path"]},
        UpdateExpression = "ADD hits: incr",
        ExpressionAttributeValues = {":incr": 1}
    )
    
    resp = _lambda.invoke(
        FunctionName= os.environ["DOWNSTREAM_FUNCTION_NAME"],
        Payload = json.dumps(event),
        
    )
    
    body = resp["Payload"].read()
    print("Downstream Response: {}".format(body))
    return json.loads(body)

hitcounter.py文件中的代码

from constructs import Construct

from aws_cdk import (
    aws_lambda as _lambda,
    aws_dynamodb as ddb,
)

class HitCounter(Construct):
    @property  # need to check what is the purpose of this decorator and the two lines of code. 
    def handler(self):
        return self._handler
    
    
    def __init__(self, scope:Construct, id:str, downstream: _lambda.IFunction, **kwargs):
        super().__init__(scope, id, **kwargs)
        
        table = ddb.Table(
            self, 'Hits',
            partition_key={'name': 'path', 'type': ddb.AttributeType.STRING}
        )
        
        self._handler = _lambda.Function(
            self,'HitCountHandler',
            runtime= _lambda.Runtime.PYTHON_3_10,
            handler='hitcount.handler',
            code = _lambda.Code.from_asset("lambda"),
            environment={
                "DOWNSTREAM_FUNCTION_NAME": downstream.function_name,
                "HITS_TABLE_NAME": table.table_name,
            }
            
        )
        
        table.grant_read_write_data(self._handler)
        downstream.grant_invoke(self._handler)
        
        

cdk_workshop_stack.py 文件中的代码

from constructs import Construct
from aws_cdk import (
    Duration,
    Stack,
    aws_lambda as _lambda,
    aws_apigateway as apigw,
)
from .hitcounter import HitCounter


class CdkWorkshopStack(Stack):

    def __init__(self, scope: Construct, construct_id: str, **kwargs) -> None:
        super().__init__(scope, construct_id, **kwargs)
        
        # Defines an AWS Lamdba resource
        
        my_lambda = _lambda.Function(
            self,
            "HelloHandler",
            runtime= _lambda.Runtime.PYTHON_3_10,
            code= _lambda.Code.from_asset("lambda"),
            handler="hello.handler",
        )
        
        # apigw.LambdaRestApi(
        #     self, "Endpoint",
        #     handler= my_lambda,
        # )
        
        hello_with_counter = HitCounter(
            self, 'HelloHitCounter',
            downstream= my_lambda,
        )
        
        apigw.LambdaRestApi(
            self, 'EndPoint',
            handler= hello_with_counter.handler,
        )
       

我在 Cloud watch 日志中看到错误

[ERROR] ParamValidationError: Parameter validation failed:
Missing required parameter in input: "Key"
Unknown parameter in input: "key", must be one of: TableName, Key, AttributeUpdates, Expected, ConditionalOperator, ReturnValues, ReturnConsumedCapacity, ReturnItemCollectionMetrics, UpdateExpression, ConditionExpression, ExpressionAttributeNames, ExpressionAttributeValues, ReturnValuesOnConditionCheckFailure
Traceback (most recent call last):
  File "/var/task/hitcount.py", line 12, in handler
    table.update_item(
  File "/var/runtime/boto3/resources/factory.py", line 581, in do_action
    response = action(self, *args, **kwargs)
  File "/var/runtime/boto3/resources/action.py", line 88, in __call__
    response = getattr(parent.meta.client, operation_name)(*args, **params)
  File "/var/runtime/botocore/client.py", line 565, in _api_call
    return self._make_api_call(operation_name, kwargs)
  File "/var/runtime/botocore/client.py", line 974, in _make_api_call
    request_dict = self._convert_to_request_dict(
  File "/var/runtime/botocore/client.py", line 1048, in _convert_to_request_dict
    request_dict = self._serializer.serialize_to_request(
  File "/var/runtime/botocore/validate.py", line 381, in serialize_to_request
    raise ParamValidationError(report=report.generate_report())

我期待在 DynamoDB 中创建一个条目

python-3.x amazon-dynamodb aws-cdk
1个回答
0
投票

在您共享的代码中,密钥为小写

k
,而按照 CDK 研讨会中的定义,它应该为大写:

import json
import os

import boto3

ddb = boto3.resource('dynamodb')
table = ddb.Table(os.environ['HITS_TABLE_NAME'])
_lambda = boto3.client('lambda')


def handler(event, context):
    print('request: {}'.format(json.dumps(event)))
    table.update_item(
        Key={'path': event['path']}, # Upper case K for Key
        UpdateExpression='ADD hits :incr',
        ExpressionAttributeValues={':incr': 1}
    )

    resp = _lambda.invoke(
        FunctionName=os.environ['DOWNSTREAM_FUNCTION_NAME'],
        Payload=json.dumps(event),
    )

    body = resp['Payload'].read()

    print('downstream response: {}'.format(body))
    return json.loads(body)

https://catalog.us-east-1.prod.workshops.aws/workshops/10141411-0192-4021-afa8-2436f3c66bd8/en-US/3000-python-workshop/400-hit-counter/420-处理者

© www.soinside.com 2019 - 2024. All rights reserved.