Skip to content

feat(data-classes): replace AttributeValue in DynamoDBStreamEvent with deserialized Python values #1619

New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Merged

Conversation

shanab
Copy link
Contributor

@shanab shanab commented Oct 19, 2022

Issue number: #1432

Summary

Add DynamoDBImageDeserializer class to data classes. The class can be used to parse DynamoDB StreamRecord's old_image and new_image properties of type Dict[str, AttrValue] to Dict with Python types.

Changes

  • Replace AttributeValue with deserialized Python types.

User experience

Users will be able to convert a StreamRecord's complex image type into a Python dictionary with Python types; without needing to recurse through the data, which was a limitation when using AttributeValue.

Please note that the following functions: new_image, old_image and keys will introduce breaking changes to users.

Old usage example:

@event_source(data_class=DynamoDBStreamEvent)
def lambda_handler(event: DynamoDBStreamEvent, context):
    for record in event.records:
        new_image: Dict[str, AttributeValue] = record.dynamodb.new_image
        event_type: AttributeValue = new_image["eventType"].get_value
        if event_type == "PENDING":
            data = get_image_data(new_image)
            send_to_sqs(data)

def get_image_data(image: Dict[str, AttributeValue]) -> Dict[str, Any]:
    # Note: the following line does not work with DynamoDB list and map types.
    # If such types are present, then one will have to recursively call `get_value`
    # to get to the underlying data.
    return {k: v.get_value for k, v in image.items()}

def send_to_sqs(data: Dict):
    body = json.dumps(data)
    # send to sqs

New usage example:

@event_source(data_class=DynamoDBStreamEvent)
def lambda_handler(event: DynamoDBStreamEvent, context):
    for record in event.records:
        new_image: Dict[str, Any] = record.dynamodb.new_image
        if new_image.get("eventType") == "PENDING":
            send_to_sqs(new_image)  # Here new_image is just a Python Dict type

def send_to_sqs(data: Dict[str, Any]):
    body = json.dumps(data)
    # send to sqs

Checklist

If your change doesn't seem to apply, please leave them unchecked.

Is this a breaking change?

Yes
RFC issue number:

Checklist:

  • Migration process documented
  • Implement warnings (if it can live side by side)

Acknowledgment

By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice.

Disclaimer: We value your time and bandwidth. As such, any pull requests created on non-triaged issues might not be successful.

TODOLIST

  • Remove all references of AttributeValue
  • Document with examples how new_image, old_image and keys are now different from how they used to work previously.

@shanab shanab requested a review from a team as a code owner October 19, 2022 10:55
@shanab shanab requested review from mploski and removed request for a team October 19, 2022 10:55
@boring-cyborg boring-cyborg bot added the tests label Oct 19, 2022
@pull-request-size pull-request-size bot added the size/L Denotes a PR that changes 100-499 lines, ignoring generated files. label Oct 19, 2022
@shanab shanab changed the title Feature/dynamodb type deserializer feat(data-classes): replace AttributeValue in DynamoDBStreamEvent with deserialized Python values Oct 19, 2022
@heitorlessa heitorlessa requested review from heitorlessa and removed request for mploski October 19, 2022 11:07
@github-actions github-actions bot added the feature New feature or functionality label Oct 19, 2022
Copy link
Contributor

@heitorlessa heitorlessa left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

peer review comments in

@boring-cyborg boring-cyborg bot added the documentation Improvements or additions to documentation label Oct 19, 2022
@pull-request-size pull-request-size bot added size/XL Denotes a PR that changes 500-999 lines, ignoring generated files. and removed size/L Denotes a PR that changes 100-499 lines, ignoring generated files. labels Oct 19, 2022
@heitorlessa
Copy link
Contributor

Pushed the upgrade guide for this with a note on Decimal too.

image

@codecov-commenter
Copy link

Codecov Report

Base: 99.40% // Head: 99.36% // Decreases project coverage by -0.03% ⚠️

Coverage data is based on head (f40c044) compared to base (2864b46).
Patch coverage: 95.45% of modified lines in pull request are covered.

Additional details and impacted files
@@            Coverage Diff             @@
##               v2    #1619      +/-   ##
==========================================
- Coverage   99.40%   99.36%   -0.04%     
==========================================
  Files         127      127              
  Lines        5842     5815      -27     
  Branches      367      370       +3     
==========================================
- Hits         5807     5778      -29     
- Misses         17       18       +1     
- Partials       18       19       +1     
Impacted Files Coverage Δ
aws_lambda_powertools/utilities/batch/base.py 97.79% <ø> (ø)
...s/utilities/data_classes/dynamo_db_stream_event.py 98.13% <95.45%> (-1.87%) ⬇️

Help us with your feedback. Take ten seconds to tell us how you rate us. Have a feature suggestion? Share it here.

☔ View full report at Codecov.
📢 Do you have feedback about the report comment? Let us know in this issue.

@heitorlessa
Copy link
Contributor

Added static typing for methods signatures and return, added last comments to help remember Decimal logic in the far future, and added a note about this being related to Batch Processing too.

Waiting for CI and we can merge!!!!

image

@heitorlessa heitorlessa merged commit bf0ae43 into aws-powertools:v2 Oct 19, 2022
@boring-cyborg
Copy link

boring-cyborg bot commented Oct 19, 2022

Awesome work, congrats on your first merged pull request and thank you for helping improve everyone's experience!

# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
documentation Improvements or additions to documentation feature New feature or functionality size/XL Denotes a PR that changes 500-999 lines, ignoring generated files. tests
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants