question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Add ConditionExpression to dynamodb batch writer

See original GitHub issue

I have a use case where I want to write a few dozen rows to dynamodb at a time, with conditions.

Use Case

But there’s a certain edge case I’m trying to handle, where I’m trying to write two sets of data to the table which describe the same thing, but one is more recent (and therefore more accurate) than the other. So I need to use dynamodb conditions to say:

I can do this with a for loop over

response = table.put_item(
            Item=row,
            ReturnValues='ALL_OLD',
            ReturnConsumedCapacity='NONE',
            ConditionExpression=cond
        )

Including the server-side atomic logic, this is basically:

for new_row in rows:
   if new_row not already in table:
      put_item(new_row) # new
   elif existing_row['t'] < new_row['t']:
      put_item() # overwite because the new row is more recent
   else:
      pass
      # do nothing, because the data in the table is newer than what we're trying to write

This is pretty slow, because there’s a separate HTTP call for each row.

I would like to use the batch writer for this, but it currently doesn’t accept Conditions.

MWE

import boto3
from boto3.dynamodb.conditions import Key, Attr

table_name = 'test_batch_write'
dynamodb = boto3.resource('dynamodb')
table = dynamodb.Table(table_name)

for delta in [0, 1]:
    with table.batch_writer() as batch:
        for i in range(10):
            val = i + delta * (i%2)
            cond = Attr('regionid').not_exists() & Attr('interval_end').not_exists() # row doesn't yet exist
            cond |= Attr('val').lt(val) # or val is lower
            print(f"Put {i}")
            batch.put_item(
                Item={
                    'top_timestamp': i,
                    'regionid': 'QLD1',
                    'val': val
                },
                ConditionExpression=cond)

Actual Result:

Traceback (most recent call last):
  File "batch_write.py", line 21, in <module>
    ConditionExpression=cond)
TypeError: put_item() got an unexpected keyword argument 'ConditionExpression'

Expected result:

Dynamodb contains 10 rows. For each row with an even i, the val column equals i which equals top_timestamp. For each other row, the val column equals i+1.

Note that with individual put calls, if the condition fails a boto3.client('dynamodb').exceptions.ConditionalCheckFailedException exception is throw which has to be caught inside each iteration over my for loop. I’m not sure what the best way to handle that for a batch write is.

Issue Analytics

  • State:open
  • Created 3 years ago
  • Reactions:25
  • Comments:9 (1 by maintainers)

github_iconTop GitHub Comments

11reactions
rrhodescommented, Feb 2, 2021

+1 for this feature, it would be hugely helpful in my work.

Took a quick look into this. It appears we need to add support for ConditionExpression into the batch_write_item method before it’s possible to fully satisfy this request. Said method doesn’t appear to be open-source, or at least I can’t find it, otherwise I would have been happy to consider adding this feature myself.

1reaction
dazzag24commented, Sep 3, 2021

+1 for this idea. I have to update a table with incremental updates and this would allow me to avoid a whole bunch of client side logic to decide if a item already exists or not.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Is it possible to batch write with conditional expression on a ...
Queries must be against a Table/Index's Primary Key (so no joining on a GSI); To the best of my knowledge you can't add...
Read more >
Condition expressions - Amazon DynamoDB
Use a condition expression in DynamoDB to indicate the conditions under which to read or write item attributes.
Read more >
Understanding DynamoDB Condition Expressions - Alex DeBrie
If you include a Condition Expression in your write operation, ... You cannot use Condition Expressions with BatchWriteItem (BatchWriteItem ...
Read more >
DynamoDB Batch Write, Update & Delete [How-To Guide]
Many developers encounter the problem of performing individual operations for data items rather than grouping them, which adds latency for each ...
Read more >
DynamoDB — Boto3 Docs 1.26.34 documentation - AWS
Amazon DynamoDB is a fully managed NoSQL database service that provides fast and ... The entire batch must consist of either read statements...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found