I have a simple Python function on AWS Lambda that just puts some data into a DynamoDB table and as far as I can tell, I'm following the correct format as per the Boto3 documentation for the put_item() function. I'm getting the following error that I can't seem to debug:
"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"
],
Here is the Python function:
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))
This is the JSON I am sending:
{
"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"
}
Use the following Client.put_item example for the Client API:
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);
Or use the following Table.put_item example for the Resource 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)
It's very easy to find that you are using a Resource-level object (such as Table) but accidentally looking at the Client-level API documentation because the methods unfortunately have the same names (e.g. put_item
).
See a related post on when to use a boto3 Client vs a Resource. The key difference here is that the Resource API marshals/unmarshals data to/from native Python data types automatically, while the Client API does not.
The float values should be set as demical in Python.
Import:-
import decimal
Set the value as decimal:-
"GSRResults": [decimal.Decimal('3.8'),decimal.Decimal('3.4')]
Dynamodb Type for Python
For types that involve numbers, it is recommended that
Decimal
objects are used to be able to round-trip the Python type.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With