簡體   English   中英

boto3 和 lambda:使用 DynamoDB 資源和 localstack 時參數 KeyConditionExpression 的類型無效

[英]boto3 and lambda: Invalid type for parameter KeyConditionExpression when using DynamoDB resource and localstack

當我嘗試從我的本地機器使用 boto3 dynamodb 資源與從 localstack 的 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 (http://localstack:4566)。

當我調用此 lamdba 時,出現以下錯誤:

{
    "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)。 但是,我將我的本地版本降級為與運行時相同的版本,並且我一直得到相同的結果。

在回答了這個問題后,我設法使代碼能夠針對實際的 AWS 服務運行,但是在針對 localstack 運行時它仍然無法運行。

我做錯了什么嗎? Os這可能是localstack的錯誤嗎?

--- 更新 1 ---

改變回報並沒有解決問題:

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

--- 更新 2 ---

該代碼在針對實際 AWS 服務運行而不是針對 localstack 運行時有效。 使用此信息更新問題。

這在我的本地機器和 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!')
    }

還要確保event["customer_id"]實際上是 eq 函數預期的字符串值。

我會檢查以確保您正確設置了端點並且部署了當前版本。

也可能是您試圖通過處理程序返回 API 調用的結果,而不是預期的正確 JSON 響應:

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

暫無
暫無

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

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