Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can we use transact_write_items without specifying attribute types?

According to the boto3 official documentation, the transact_write_items method is only available on the dynamodb client, not the dynamodb ServiceResource. The nice thing about methods on the dynamodb ServiceResource vs the client is that ServiceResource methods don't require you to parse your own attribute types. You can plug in a basic python dictionary as an item rather than needing to specify every value's attribute type.

Here's an example of using a client to insert an item:

import boto3
client = boto3.client('dynamodb')
client.put_item(
    Item={
        'AlbumTitle': {
            'S': 'Somewhat Famous',
        },
        'Artist': {
            'S': 'No One You Know',
        },
        'SongTitle': {
            'S': 'Call Me Today',
        },
        'NestedValue': {
            'M': {
                'a': {'S': 'apple'},
                'b': {'L': [
                    {'S': 'something else'},
                    {'S': 'another value'}
                ]}
            }
    },
    ReturnConsumedCapacity='TOTAL',
    TableName='Music',
)

Here's an example of using a ServiceResource to insert an item:

import boto3
dynamodb = boto3.resource('dynamodb')
table = dynamodb.Table('Music')
table.put_item(
    Item={
        'AlbumTitle': 'Somewhat Famous',
        'Artist': 'No One You Know',
        'SongTitle': 'Call Me Today',
        'NestedValue': {
            'a': 'apple',
            'b': [
                'something else',
                'another value'
            ]
        }
    },
)

It is much cleaner to use a dynamodb ServiceResource, especially for complicated nested values. As a workaround, I've been writing a parser that converts a python dictionary into a dynamodb-digestible dictionary. This should work, but it wouldn't be as simple or secure as letting boto3 handle that for me. This is all because transact_write_items is not available on a ServiceResource.

Unless it is? A dynamodb ServiceResource dynamodb = boto3.resource('dynamodb') has a client inside it's meta object. dynamodb.meta.client.transact_write_items is a valid, seemingly functional instance of transact_write_items. And it seems to automatically parse my item dictionary without needing to specify attribute types.

import boto3
dynamodb = boto3.resource('dynamodb')
dynamodb.meta.client.transact_write_items(Items=[
    {
        "Put": {
            "TableName": "test",
            "Item": {
                "pk": "a",
                "sk": "b"
            },
            "ReturnValuesOnConditionCheckFailure": "ALL_OLD",
        }
    }
])

vs.

import boto3
client = boto3.client('dynamodb')
client.transact_write_items(Items=[
    {
        "Put": {
            "TableName": "test",
            "Item": {
                "pk": {"S": "a"},
                "sk": {"S": "b"}
            },
            "ReturnValuesOnConditionCheckFailure": "ALL_OLD",
        }
    }
])

Is this a viable solution? Can I use dynamodb.meta.client.transact_write_items to use transact_write_items with all the automated attribute parsing benefits that come from using ServiceResource methods? Are there unintended side effects that I'm not aware of? It doesn't feel right calling a method nested deep into the meta attribute, but I can't find another cleaner way to get what I'm looking for.

Documentation that might help:

  • Boto3 official documentation for transact_write_items: https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/dynamodb.html#DynamoDB.Client.transact_write_items
  • relevant github thread: https://github.com/boto/botocore/issues/1726
like image 406
niicck Avatar asked Aug 14 '26 13:08

niicck


1 Answers

Apparently this is the expected behavior of boto3. One developer's bug is another developer's feature.

https://github.com/boto/boto3/issues/2391

like image 82
niicck Avatar answered Aug 16 '26 01:08

niicck



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!