j doe
j doe

Reputation: 1

Requesting help triggering a lambda function from DynamoDB

I was following the guide posted here on youtube https://www.youtube.com/watch?v=jgiZ9QUYqyM and is defiantly what I want. I posted the code that I had for mine and the image of what everything looks like in my AWS.

I have a dynamodb table and linked it to my s3 bucket with a trigger. That trigger is giving me some error message which is posted above. "Decimal('1') is not JSON serializable". Though I was testing it with the helloworld.

This is the code :

import boto3
import json
import os
s3 =  boto3.client('s3')
ddb = boto3.resource('dynamodb')
table = ddb.Table('test_table')


def lambda_handler(event, context):
  response = table.scan()
  body = json.dumps(response['Items'])
  response = s3.put_object(Bucket='s3-testing',
  Key = 's3-testing.json' ,
  Body=body,
  ContentType='application/json')

Can someone point me in the right direction? These are the snippets I got

https://i.sstatic.net/I0jAn.png

https://i.sstatic.net/2hMc9.png

This is the execution log:

Response:
{
  "stackTrace": [
    [
      "/var/task/lambda_function.py",
      20,
      "lambda_handler",
      "body = json.dumps(response['Items'])"
    ],
    [
      "/usr/lib64/python2.7/json/__init__.py",
      244,
      "dumps",
      "return _default_encoder.encode(obj)"
    ],
    [
      "/usr/lib64/python2.7/json/encoder.py",
      207,
      "encode",
      "chunks = self.iterencode(o, _one_shot=True)"
    ],
    [
      "/usr/lib64/python2.7/json/encoder.py",
      270,
      "iterencode",
      "return _iterencode(o, 0)"
    ],
    [
      "/usr/lib64/python2.7/json/encoder.py",
      184,
      "default",
      "raise TypeError(repr(o) + \" is not JSON serializable\")"
    ]
  ],
  "errorType": "TypeError",
  "errorMessage": "Decimal('1') is not JSON serializable"
}

Function log:

    START RequestId: 31719509-94c7-11e8-a0d4-a9b76b7b212c Version: $LATEST
Decimal('1') is not JSON serializable: TypeError
Traceback (most recent call last):
  File "/var/task/lambda_function.py", line 20, in lambda_handler
    body = json.dumps(response['Items'])
  File "/usr/lib64/python2.7/json/__init__.py", line 244, in dumps
    return _default_encoder.encode(obj)
  File "/usr/lib64/python2.7/json/encoder.py", line 207, in encode
    chunks = self.iterencode(o, _one_shot=True)
  File "/usr/lib64/python2.7/json/encoder.py", line 270, in iterencode
    return _iterencode(o, 0)
  File "/usr/lib64/python2.7/json/encoder.py", line 184, in default
    raise TypeError(repr(o) + " is not JSON serializable")
TypeError: Decimal('1') is not JSON serializable

Upvotes: 0

Views: 1924

Answers (2)

Prajilesh
Prajilesh

Reputation: 691

Decimal object is not json serializable. Considering casting the Decimal into a float using a helper function. (json.dumps() takes a default function)

import boto3
import json
import os

from decimal import Decimal
s3 =  boto3.client('s3')
ddb = boto3.resource('dynamodb')
table = ddb.Table('test_table')


def lambda_handler(event, context):
  response = table.scan()
  body = json.dumps(response['Items'], default=handle_decimal_type)
  response = s3.put_object(Bucket='s3-testing',
  Key = 's3-testing.json' ,
  Body=body,
  ContentType='application/json')


def handle_decimal_type(obj):
  if isinstance(obj, Decimal):
      if float(obj).is_integer():
         return int(obj)
      else:
         return float(obj)
  raise TypeError

Upvotes: 3

Brian Winant
Brian Winant

Reputation: 3035

The problem is that the Dynamo Python library is converting numeric values to Decimal objects, but those aren't JSON serializable by default, so json.dumps blows up. You will need to provide json.dumps with a converter for Decimal objects.

See Python JSON serialize a Decimal object

Upvotes: 0

Related Questions