【问题标题】:boto3 and lambda: Invalid type for parameter KeyConditionExpression when using DynamoDB resourceboto3 和 lambda:使用 DynamoDB 资源时参数 KeyConditionExpression 的类型无效
【发布时间】:2022-12-16 23:50:31
【问题描述】:

尝试从我的本地计算机使用 boto3 dynamodb 资源与从 lambda 函数中使用时,我得到的结果非常不一致。我有以下简单的 lambda 处理程序,它只查询基于哈希键的表:

import boto3
from boto3.dynamodb.conditions import Key

def handler(event, context):
    dynamodb = boto3.resource(
        "dynamodb", endpoint_url=os.environ["AWS_EP"]
    )
    table = dynamodb.Table("precalculated_scores")
    items = table.query(
        KeyConditionExpression=Key("customer_id").eq(event["customer_id"])
    )
    return items

原型设计时,环境变量“AWS_EP”设置为我的 localstack DNS。否则,它指向实际的 AWS 服务。

当我调用此 lambda 时,出现以下错误:

{
    "errorMessage": "Parameter validation failed:\nInvalid type for parameter KeyConditionExpression, value: <boto3.dynamodb.conditions.Equals object at 0x7f7440201960>, type: <class 'boto3.dynamodb.conditions.Equals'>, valid types: <class 'str'>",
    "errorType": "ParamValidationError",
    "stackTrace": [
        "  File \"/opt/code/localstack/localstack/services/awslambda/lambda_executors.py\", line 1423, in do_execute\n    execute_result = lambda_function_callable(inv_context.event, context)\n",
        "  File \"/opt/code/localstack/localstack/services/awslambda/lambda_api.py\", line 782, in exec_local_python\n    return inner_handler(event, context)\n",
        "  File \"/var/lib/localstack/tmp/lambda_script_l_dbef16b3.py\", line 29, in handler\n    items = table.query(\n",
        "  File \"/opt/code/localstack/.venv/lib/python3.10/site-packages/boto3/resources/factory.py\", line 580, in do_action\n    response = action(self, *args, **kwargs)\n",
        "  File \"/opt/code/localstack/.venv/lib/python3.10/site-packages/boto3/resources/action.py\", line 88, in __call__\n    response = getattr(parent.meta.client, operation_name)(*args, **params)\n",
        "  File \"/opt/code/localstack/.venv/lib/python3.10/site-packages/botocore/client.py\", line 514, in _api_call\n    return self._make_api_call(operation_name, kwargs)\n",
        "  File \"/opt/code/localstack/.venv/lib/python3.10/site-packages/botocore/client.py\", line 901, in _make_api_call\n    request_dict = self._convert_to_request_dict(\n",
        "  File \"/opt/code/localstack/.venv/lib/python3.10/site-packages/botocore/client.py\", line 962, in _convert_to_request_dict\n    request_dict = self._serializer.serialize_to_request(\n",
        "  File \"/opt/code/localstack/.venv/lib/python3.10/site-packages/botocore/validate.py\", line 381, in serialize_to_request\n    raise ParamValidationError(report=report.generate_report())\n"
    ]
}

这是一个奇怪的错误——根据我对其他问题的研究,它通常在使用 boto3 客户端时发生,但我使用的是 boto3 资源。此外,当我在我的机器上本地运行代码时,它运行良好。

起初我认为这可能是由于 boto3 的不同版本(我的本地机器使用的是 1.24.96 版本,而 lambda 运行时内部的版本是 1.16.31)。但是,我将我的本地版本降级为与运行时相同的版本,并且我一直得到相同的结果。

我做错了什么吗?

- - 编辑 - -

改变回报并没有解决问题:

return {"statusCode": 200, "body": json.dumps(items)}

【问题讨论】:

  • 在 Lambda 中运行时删除 endpoint_url 参数是否有任何影响?您是否打印了event["customer_id"] 以确保它是一个具有合理值的字符串?

标签: aws-lambda amazon-dynamodb boto3


【解决方案1】:

这在我的本地机器和 Lambda 上都运行良好:

import json, boto3
from boto3.dynamodb.conditions import Key


def lambda_handler(event, context):
    dynamodb = boto3.resource(
    "dynamodb",
     endpoint_url="https://dynamodb.eu-west-1.amazonaws.com"
    )
    table = dynamodb.Table("test")
    items = table.query(
        KeyConditionExpression=Key("pk").eq("1")
    )
    print(items)

    return {
        'statusCode': 200,
        'body': json.dumps('Hello from Lambda!')
    }

我会检查以确保您正确设置了端点并且部署了当前版本。

也可能是您试图通过处理程序返回 API 调用的结果,而不是预期的正确 JSON 响应:

    return {
        'statusCode': 200,
        'body': json.dumps(items)
    }

【讨论】:

  • 试图更新返回码,但无济于事。该错误是由于调用 table.query 时出现未处理的异常而发生的。我越来越怀疑这可能是 localstack 的某种奇怪的错误/怪癖。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-09-26
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多