I have a strange problem with Python Boto3 when trying to do a batch_write_item to a DynamoDB table. I am following the documentation and trying to write a singe item. The table is setup correctly and I can run batch-write-item via the AWS cli no problem.
Assuming the client and DynamoDB are set up correctly I run:
client.batch_write_item(RequestItems={
"myTable": [
{
"PutRequest": {
"Item": {
"name": {
"S": "hello"
},
"value": {
"S": "world"
}
}
}
}
]
})
I get the following error:
botocore.exceptions.ClientError: An error occurred (ValidationException) when calling the BatchWriteItem operation: Invalid attribute value type
If I change it, removing the types and run:
client.batch_write_item(RequestItems={
"myTable": [
{
"PutRequest": {
"Item": {
"name": "hello",
"value": "world"
}
}
}
]
})
It works as expected.
I need to use the previous format which follows the documentation and is compatibale with AWS cli.
Is the documentation wrong or I missed a configuration setting, version issue or something else?
List of DynamoDB Boto3 Query Examples 1 Connecting Boto3 to DynamoDB 2 Create Table 3 Get All Items / Scan 4 Get Item 5 Batch Get Item 6 Put Item 7 Query Set of Items 8 Update Item 9 Conditionally Update Item 10 Increment Item Attribute 11 Delete Item 12 Delete All Items 13 Query with Sorting 14 Query Pagination 15 Run DynamoDB Local More ...
With BatchWriteItem, you can efficiently write or delete large amounts of data, such as from Amazon EMR, or copy data from another database into DynamoDB. In order to improve performance with these large-scale operations, BatchWriteItem does not behave in the same way as individual PutItem and DeleteItem calls would.
Boto3 Put Item To write a single item into the DynamoDB Table, use PutItem operation: import boto3 dynamodb = boto3.resource('dynamodb', region_name=region) table = dynamodb.Table('my-table') response = table.put_item( Item={ 'id': 1, 'title': 'my-document-title', 'content': 'some-content', } )
Boto3 Conditionally Update Item Moreover, you can also add a ConditionExpression parameter, which restricts the update logic only if the evaluated expression equals true. import boto3 dynamodb = boto3. resource ('dynamodb', region_name = region) table = dynamodb.
This just got me as well, looks like you're using a DynamoDB resource, not a client. They both provide the same function but it acts very slightly differently. Here's what you're looking for:
http://boto3.readthedocs.io/en/latest/reference/services/dynamodb.html#DynamoDB.ServiceResource.batch_write_item
That aside, the docs are still pretty unclear. Here's what I found:
Using the DynamoDB resource:
resource = boto3.resource('dynamodb', endpoint_url='http://localhost:8000')
mytable = resource.create_table(
TableName='mytable',
KeySchema=[{ 'AttributeName': 'name', 'KeyType': 'HASH' }],
AttributeDefinitions=[{ 'AttributeName': 'name', 'AttributeType': 'S' }],
ProvisionedThroughput={ 'ReadCapacityUnits': 5, 'WriteCapacityUnits': 5 }
)
try:
resource.batch_write_item(RequestItems={
'mytable': [{ 'PutRequest': { 'Item': {
'name': { 'S': 'myname' },
'value': { 'S': 'myvalue' }
}}}]
})
print(f'resource, specify all types : write succeeded.')
except Exception as e:
print(f'resource, specify all types : write failed: {e}')
try:
resource.batch_write_item(RequestItems={
'mytable': [{ 'PutRequest': { 'Item': {
'name': 'myname',
'value': { 'S': 'myvalue' }
}}}]
})
print(f'resource, specify value only: write succeeded.')
except Exception as e:
print(f'resource, specify value only: write failed: {e}')
try:
resource.batch_write_item(RequestItems={
'mytable': [{ 'PutRequest': { 'Item': {
'name': 'myname',
'value': 'myvalue'
}}}]
})
print(f'resource, specify none : write succeeded.')
except Exception as e:
print(f'resource, specify none : write failed: {e}')
Output
resource, specify all types : write failed:
An error occurred (ValidationException) when calling the BatchWriteItem operation: Invalid attribute value type
resource, specify value only: write succeeded.
resource, specify none : write succeeded.
And then using the DynamoDB client (replace all "resource"s above with client)
client = boto3.client('dynamodb', endpoint_url='http://localhost:8000')
try:
client.batch_write_item(RequestItems={
....
Output
client, specify all types : write succeeded.
client, specify value only: write failed: Parameter validation failed:
Invalid type for parameter RequestItems.mytable[0].PutRequest.Item.name, value: myname, type: <class 'str'>, valid types: <class 'dict'>
client, specify none : write failed: Parameter validation failed:
Invalid type for parameter RequestItems.mytable[0].PutRequest.Item.name, value: myname, type: <class 'str'>, valid types: <class 'dict'>
Invalid type for parameter RequestItems.mytable[0].PutRequest.Item.value, value: myvalue, type: <class 'str'>, valid types: <class 'dict'>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With