Ryan Davies
Ryan Davies

Reputation: 616

DynamoDB Conditional Put_Item

Hi Stackoverflow I'm trying to conditionally put an item within a DynamoDB table. The DynamoDB table has the following attributes.

Every minute I'm calling an API which gives me a minute by minute list of dictionaries for all stock prices within the day so far. However, the data I receive from the API sometimes can be behind by a minute or two. I don't particularly want to overwrite all the records within the DynamoDB table every time I get new data. To achieve this I've tried to create a conditional expression to only use put_item when there is a match on ticker but there is a new price_date

I've created a simplification of my code below to better illustrate my problem.

import boto3
from boto3.dynamodb.conditions import Attr

dynamodb = boto3.resource('dynamodb')
table = dynamodb.Table('stock-intraday')

data = [
    {'ticker': 'GOOG', 'price_date': '2021-10-08T9:30:00.000Z', 'price': 100},
    {'ticker': 'GOOG', 'price_date': '2021-10-08T9:31:00.000Z', 'price': 101}
]

for item in data:
    dynamodb_response = table.put_item(Item=item,
                                       ConditionExpression=Attr("ticker").exists() & Attr("price_date").not_exists())

However when I run this code I get this error...

enter image description here

What is wrong with my conditional expression?

Upvotes: 0

Views: 814

Answers (1)

Ryan Davies
Ryan Davies

Reputation: 616

Found an answer to my own problem. DynamoDB was throwing an error because my code WAS working but with some minor changes.

There needed to be a TRY EXCEPT block but also since the partition key is already evaluated only the price_date needed to be included within the condition expression

import boto3
from boto3.dynamodb.conditions import Attr
from botocore.exceptions import ClientError

dynamodb = boto3.resource('dynamodb')
table = dynamodb.Table('stock-intraday')

data = [
{'ticker': 'GOOG', 'price_date': '2021-10-08T9:30:00.000Z', 'price': 100},
{'ticker': 'GOOG', 'price_date': '2021-10-08T9:31:00.000Z', 'price': 101}]

for item in data:
    try:
        dynamodb_response = table.put_item(Item=item,
                                       ConditionExpression=Attr("price_date").not_exists())
    except ClientError as e:
        if e.response['Error']['Code'] == 'ConditionalCheckFailedException':
            pass

Upvotes: 0

Related Questions