【问题标题】:ParameterVailidation Failed When Sending List to DynamoDB将列表发送到 DynamoDB 时参数验证失败
【发布时间】:2017-11-01 17:21:39
【问题描述】:

我在 AWS Lambda 上有一个简单的 Python 函数,它只是将一些数据放入 DynamoDB 表中,据我所知,我按照 put_item() 函数的 Boto3 文档遵循正确的格式。我收到以下似乎无法调试的错误:

"errorMessage": 
"Parameter validation failed:\nInvalid type for parameter 
Item.GSRResults.L[0], value: 3.8, type: <class 'float'>, valid types: <class 'dict'>
\nInvalid type for parameter Item.GSRResults.L[1], value: 3.4, type: <class 'float'>, valid types: <class 'dict'>\... snip...
\nInvalid type for parameter Item.GSRResults.L[9], value: 3.3, type: <class 'float'>, valid types: <class 'dict'>",
  "errorType": "ParamValidationError",
  "stackTrace": [
    [
      "/var/task/index.py",
      39,
      "upload_test",
      "Item=item"
    ], 

这里是 Python 函数:

def upload_test(event, context):
    if event['httpMethod'] == 'POST':
        info = event['body']
        item = info['Item']
        return respond(None, dynamo.put_item(
            TableName="TestResults",
            Item=item))

这是我发送的 JSON:

{
  "body": {
    "Item": {
      "UID": {
        "S": "U999999"
      },
      "PID": {
        "S": "P444444"
      },
      "GSRResults": { "L": [3.8,3.4,3.3,2.8,1.3,3.2,4.3,2.1,3.2,3.3] }
    }
  },
  "httpMethod": "POST"
}

【问题讨论】:

  • DynamoDB 不允许插入浮点值。
  • @Asdfg 感谢您的回复。在文档中他们给出的示例之一:"L": ["Cookies", "Coffee", 3.14159]
  • Dynamodb 确实允许将浮点值存储为数字。
  • 该示例可能不适用于 Python。 Python 将 3.8 视为浮点数,而其他可能将其视为十进制。我想,但我在这里可能是错的。
  • 如果我将这些值更改为 int's 或 str's,我仍然会遇到不同类型的相同错误。

标签: python json amazon-web-services amazon-dynamodb aws-lambda


【解决方案1】:

对客户端 API 使用以下 Client.put_item 示例:

import boto3
client = boto3.client('dynamodb')

item1 = {
  "id": {
    "S": "1",
  },
  "name": {
    "S": "Testing"
  },
  "age": {
    "N": "22"
  },
  "grades": {
    "L": [ {"N": "3.50"}, {"N": "3.1415926"} ]
  }
}

client.put_item(TableName='test', Item=item1);

或使用以下 Table.put_item 示例作为资源 API:

import boto3
dynamodb = boto3.resource('dynamodb')
table = dynamodb.Table('test')

item2 = {
  "id": "2",
  "name": "Testing2",
  "age": 22,
  "grades": [ decimal.Decimal('3.50'), decimal.Decimal('3.1415926') ]
}

table.put_item(Item=item2)

很容易发现您正在使用资源级对象(例如 Table),但不小心查看了客户端级 API 文档,因为不幸的是这些方法具有相同的名称(例如 put_item)。

查看related post,了解何时使用 boto3 ClientResource。此处的主要区别在于,资源 API 会自动将数据编组/解组到原生 Python 数据类型,而客户端 API 则不会。

【讨论】:

  • 这样就搞定了,非常感谢!这是我第一次使用 Lambda 和 DynamoDB,所以我仍在学习如何正确格式化所有数据。我想在检索数据时,我需要解析这个字典列表并获取列表中的所有值。有点不方便,但至少现在可以了。
【解决方案2】:

浮点值应该在 Python 中设置为 demical。

导入:-

import decimal

将值设置为十进制:-

"GSRResults": [decimal.Decimal('3.8'),decimal.Decimal('3.4')]

Dynamodb Type for Python

对于涉及数字的类型,建议Decimal 对象用于能够往返 Python 类型。

【讨论】:

  • 我试过了,它仍然在抱怨类型不是dict。
  • 我已经测试过了。这对我来说可以。我没有在 json 字符串中明确输入“L”。我的 jsonString = {"storage_CACHE_KEY": "2", "GSRResults": [decimal.Decimal('3.8'),decimal.Decimal('3.4')] }
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-09-09
  • 1970-01-01
  • 2023-02-07
  • 2018-01-22
  • 1970-01-01
  • 2021-04-01
  • 2019-12-09
相关资源
最近更新 更多