0

I'm trying to modify a Dynamodb table each time a Lambda function is executed. Specifically, I create a simple lambda function that returns a list of S3 bucket names and this function run each minute thanks to a Cloudwatch's rule. However, as I said before, my goal is to also update a Dynamodb each time the same function is executed. Specifically I want to add each time a new Item with the same attribute (so let's say the function is executed 1000 times, I want 1K items/rows).

However I don't know how to do it. Any suggestions? Here's the code:

import json
import boto3

s3 = boto3.resource('s3')
dynamodb = boto3.resource('dynamodb')
table = dynamodb.Table('Table')

def lambda_handler(event, context):
    
    bucket_list = []
    for b in s3.buckets.all():
        print(b.name)
        bucket_list.append(b.name)
        
    response = "done"
    table.put_item(
        Item = {
            "Update": response
        }
        )
    return {
        "statusCode": 200,
        "body": bucket_list
    }

Thank you in advance

V_20_sl
  • 45
  • 2
  • 10
  • What's wrong with the code? Any errors – Marcin Apr 20 '21 at 09:29
  • No errors, the code works but the final table in Dynamodb remains with one row only. Instead what I want is that every time the file is executed a row is added to the db...maybe istead of using "Item" I should use a cloudwatch log id of the event...but I don't know how to get it – V_20_sl Apr 20 '21 at 10:01
  • maybe instead of using "Item" = { "Update": "done"}, it will be better to have specific log id = {"Update": specific log timestamp} but again..I don't know how to do it – V_20_sl Apr 20 '21 at 10:13
  • I don't know what is the structure of your db, but you seem not to be setting up any primary key for your table. – Marcin Apr 20 '21 at 10:21
  • Forget to mention. I have added It manually to the Dynamodb. Is "Update" – V_20_sl Apr 20 '21 at 10:56

2 Answers2

2

Your problem is that PutItem does overwrite exiting items, if they are the same. So every time you try to insert Update=done, it just overwrites the same item.

The very first sentence of the documentation states:

Creates a new item, or replaces an old item with a new item.

So what you need to do is to put something in your item that is unique, so that a new item is created instead of the old one being overwritten.

You could create a UUID or something like that, but I think it would be beneficial to use the time of execution. This way you could see when your last execution was etc.

from datetime import datetime

[...]

table.put_item(
    Item = {
        "Update": response,
        "ProcessingTime": datetime.now().isoformat()
    }
)
Jens
  • 20,533
  • 11
  • 60
  • 86
2

Adding to what Jens stated, which is 100% correct.

You could use data from the event. The event will look something like this:

{
  "id": "cdc73f9d-aea9-11e3-9d5a-835b769c0d9c",
  "detail-type": "Scheduled Event",
  "source": "aws.events",
  "account": "123456789012",
  "time": "1970-01-01T00:00:00Z",
  "region": "us-west-2",
  "resources": [
    "arn:aws:events:us-west-2:123456789012:rule/ExampleRule"
  ],
  "detail": {}
}

The id value will be 100% unique, and the time value will be the time it was triggered.

Jason Wadsworth
  • 8,059
  • 19
  • 32
  • Uh. That's a great idea to either use the `id` or `time`. Did not think about that. – Jens Apr 20 '21 at 20:56