boto / boto3

AWS SDK for Python
https://aws.amazon.com/sdk-for-python/
Apache License 2.0
8.99k stars 1.86k forks source link

Add note regarding bitwise operator usage on DynamoDB conditions page #4117

Open SamStephens opened 4 months ago

SamStephens commented 4 months ago

Describe the issue

I raised https://github.com/boto/boto3/issues/4112 because I thought DynamoDB attribute expression AND/OR/NOT conditions were not available via boto3.

However they are available as shown in https://github.com/boto/boto3/blob/096e45841545f24bbd572a62504cc0dbb62e6b07/boto3/dynamodb/conditions.py#L158-L238

However https://boto3.amazonaws.com/v1/documentation/api/latest/reference/customizations/dynamodb.html#dynamodb-conditions does not include documentation of these conditions.

Links

https://boto3.amazonaws.com/v1/documentation/api/latest/reference/customizations/dynamodb.html#dynamodb-conditions

tim-finnigan commented 4 months ago

Thanks for raising this issue — I brought this up for discussion with the team and it was noted that the AND/OR/NOT are intentionally excluded from that documentation and the recommendation is to use Python bitwise operators instead.

github-actions[bot] commented 4 months ago

This issue is now closed. Comments on closed issues are hard for our team to see. If you need more assistance, please open a new issue that references this one.

SamStephens commented 4 months ago

@tim-finnigan I don't understand how you use Python bitwise operators to achieve the same thing as AND/OR/NOT, and I failed to find anything about this in the documentation. Can you please provide an example, or preferably a documentation link? Thanks.

tim-finnigan commented 4 months ago

@SamStephens to use bitwise operators you can try the following:

import boto3
from boto3.dynamodb.conditions import Attr

# Create a DynamoDB resource
dynamodb = boto3.resource('dynamodb')

# Specify the table name
table_name = 'test_table'
table = dynamodb.Table(table_name)

# Update an item's string attribute based on a condition expression
item_id = 'foo-key'
update_expression = 'SET item_name = :new_name'
condition_expression = Attr('item_status').exists() & Attr('item_status').eq('active')
expression_attribute_values = {
    ':new_name': 'Updated item'
}

# Execute the update operation with the condition expression
table.update_item(
    Key={'id': item_id},
    UpdateExpression=update_expression,
    ConditionExpression=condition_expression,
    ExpressionAttributeValues=expression_attribute_values
)

Or you can use standard comparison operators as documented in the DynamoDB user guide. For example:

import boto3

# Create a DynamoDB resource
dynamodb = boto3.resource('dynamodb')

# Specify the table name
table_name = 'test_table'
table = dynamodb.Table(table_name)

# Update an item's string attribute based on a condition expression
item_id = 'foo-key'
update_expression = 'SET item_name = :new_name'
condition_expression = 'attribute_exists(item_status) AND item_status = :active_status'
expression_attribute_values = {
    ':new_name': 'Updated item',
    ':active_status': 'active'
}

# Execute the update operation with the condition expression
table.update_item(
    Key={'id': item_id},
    UpdateExpression=update_expression,
    ConditionExpression=condition_expression,
    ExpressionAttributeValues=expression_attribute_values
)
SamStephens commented 4 months ago

@tim-finnigan I don't see any documentation of either the ability to use bitwise operators with boto3.dynamodb.conditions.Attr as you show in your example, or documentation of the usage of a string as a condition expression.

Why are AND/OR/NOT are intentionally excluded from that documentation? Is it because they're consider too complex? Is it because boto3.dynamodb.conditions.And, .Or and .Not are not recommended to use (should they be deprecated)? Because the ability to combine conditions is important.

As far as using a bare string for condition_expression, it's documented in the API documentation you link to, but not the boto3 documentation. Reading that documentation, I thought you had to use the classes provided in boto3.dynamodb.conditions.

tim-finnigan commented 4 months ago

@SamStephens I don't think you saw the update to my previous comment - that now includes an example using a bitwise operator. Even though AND/OR/NOT was originally included in the conditions file, those aren't documented for Boto3 because the team recommends using the existing Python operators.

SamStephens commented 4 months ago

@tim-finnigan I saw your comment. What I'm saying is the fact that bitwise operators can be applied to the classes in boto3.dynamodb.conditions.* is not discoverable from the boto3 documentation - I wouldn't know if you didn't tell me.

tim-finnigan commented 4 months ago

I see, thanks for clarifying — it looks like an example of bitwise operators can be found here: https://boto3.amazonaws.com/v1/documentation/api/latest/guide/dynamodb.html#querying-and-scanning

You are also able to chain conditions together using the logical operators: & (and), | (or), and ~ (not)...

But for better visibility I think a note describing that could also be added somewhere here to show on that documentation page. I'll reopen this and update the title.