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.

mock_dynamodb2 throws ConditionalCheckFailedException with simple put_item

See original GitHub issue

Hi, I’m trying to understand how to use the mock_dynamodb2 decorator, if I run it as is with my current code it’s throwing ConditionalCheckFailedException with write operations. Here there is a simple tests showing what happens:

'''broken_test.py'''
import boto
import botocore
import boto3
import moto

@moto.mock_dynamodb2
def test_dynamodb_put():
    '''Test data abstraction layer.'''
    assert boto.__version__ == '2.46.1'
    assert botocore.__version__ == '1.5.26'
    assert boto3.__version__ == '1.4.4'
    assert moto.__version__ == '0.4.31'

    dyn = boto3.client('dynamodb')
    dyn.create_table(
        TableName='test',
        AttributeDefinitions=[
            {'AttributeName':'email', 'AttributeType':'S'},
        ],
        KeySchema=[{'AttributeName':'email', 'KeyType':'S'}],
        ProvisionedThroughput={'ReadCapacityUnits':5, 'WriteCapacityUnits':5},
    )
    dyn.put_item(
        TableName='test',
        Item={'email': {'S': 'some@email.com'}})
$ py.test
======================================================== test session starts ========================================================
platform darwin -- Python 2.7.10, pytest-3.0.7, py-1.4.33, pluggy-0.4.0
rootdir: ./backend, inifile:
collected 1 items

broken_test.py F

============================================================= FAILURES ==============================================================
_________________________________________________________ test_dynamodb_put _________________________________________________________

    @moto.mock_dynamodb2
    def test_dynamodb_put():
        '''Test data abstraction layer.'''
        assert version.startswith('2.7.10 ')
        assert boto.__version__ == '2.46.1'
        assert botocore.__version__ == '1.5.26'
        assert boto3.__version__ == '1.4.4'
        assert moto.__version__ == '0.4.31'

        dyn = boto3.client('dynamodb')
        dyn.create_table(
            TableName='test',
            AttributeDefinitions=[
                {'AttributeName':'email', 'AttributeType':'S'},
            ],
            KeySchema=[{'AttributeName':'email', 'KeyType':'S'}],
            ProvisionedThroughput={'ReadCapacityUnits':5, 'WriteCapacityUnits':5},
        )
        dyn.put_item(
            TableName='test',
>           Item={'email': {'S': 'some@email.com'}})

broken_test.py:27:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
../../../Library/Python/2.7/lib/python/site-packages/botocore/client.py:253: in _api_call
    return self._make_api_call(operation_name, kwargs)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

self = <botocore.client.DynamoDB object at 0x106efc610>, operation_name = 'PutItem'
api_params = {'Item': {'email': {'S': 'some@email.com'}}, 'TableName': 'test'}

    def _make_api_call(self, operation_name, api_params):
        operation_model = self._service_model.operation_model(operation_name)
        request_context = {
            'client_region': self.meta.region_name,
            'client_config': self.meta.config,
            'has_streaming_input': operation_model.has_streaming_input
        }
        request_dict = self._convert_to_request_dict(
            api_params, operation_model, context=request_context)

        handler, event_response = self.meta.events.emit_until_response(
            'before-call.{endpoint_prefix}.{operation_name}'.format(
                endpoint_prefix=self._service_model.endpoint_prefix,
                operation_name=operation_name),
            model=operation_model, params=request_dict,
            request_signer=self._request_signer, context=request_context)

        if event_response is not None:
            http, parsed_response = event_response
        else:
            http, parsed_response = self._endpoint.make_request(
                operation_model, request_dict)

        self.meta.events.emit(
            'after-call.{endpoint_prefix}.{operation_name}'.format(
                endpoint_prefix=self._service_model.endpoint_prefix,
                operation_name=operation_name),
            http_response=http, parsed=parsed_response,
            model=operation_model, context=request_context
        )

        if http.status_code >= 300:
            error_code = parsed_response.get("Error", {}).get("Code")
            error_class = self.exceptions.from_code(error_code)
>           raise error_class(parsed_response, operation_name)
E           ConditionalCheckFailedException: An error occurred (ConditionalCheckFailedException) when calling the PutItem operation:

../../../Library/Python/2.7/lib/python/site-packages/botocore/client.py:543: ConditionalCheckFailedException
===================================================== 1 failed in 0.73 seconds ======================================================

I’m can’t understand which condition is not met. I’m testing on MacOS using mocks, installed Moto via pip. Thanks for your help

Issue Analytics

  • State:closed
  • Created 7 years ago
  • Reactions:1
  • Comments:6

github_iconTop GitHub Comments

1reaction
verkhorocommented, Apr 18, 2017

In my case there’s a bug in moto/dynamodb2/responses.py:430. delete_item returns an error if the item doesn’t exist.

I decided not to create a pull request for this because I don’t know dynamodb contract for consumed read capacity for this operation. I also don’t know the contract for returning attributes when the item doesn’t exist.

Ref: DeleteItemResult com.amazonaws.services.dynamodbv2.AmazonDynamoDB.deleteItem(DeleteItemRequest deleteItemRequest)

Deletes a single item in a table by primary key. You can perform a conditional delete operation that deletes the item if it exists, or if it has an expected attribute value.

In addition to deleting an item, you can also return the item’s attribute values in the same operation, using the ReturnValues parameter.

Unless you specify conditions, the DeleteItem is an idempotent operation; running it multiple times on the same item or attribute does not result in an error response.

Conditional deletes are useful for deleting items only if specific conditions are met. If those conditions are met, DynamoDB performs the delete. Otherwise, the item is not deleted

0reactions
shaftoecommented, May 4, 2017

@JackDanger I’m confused, in my case I use the put method just after creating the table, which I expect to be empty. Anyway, looking at the example you mentioned I tend to think I completely misunderstood how to actually use the library 😃 I’ll do some cargo-cult programming and get back

Read more comments on GitHub >

github_iconTop Results From Across the Web

DynamoDB put-item ConditionalCheckFailedException
Your goal is to save both records. There are 2 issues here. With your choice of hash and range key it is impossible...
Read more >
[Solved] DynamoDB ConditionalCheckFailedException
ConditionalCheckFailedException is an error thrown by AWS SDK or CLI when the ConditionExpression evaluates to false. This is especially useful if you want ......
Read more >
AppSync: how to error on DynamoDB conditional check failures
To make an AppSync DynamoDB resolver throw exceptions on conditional check errors, we need to check $context.error in the response mapping ...
Read more >
com.amazonaws.services.dynamodbv2.model. ...
public AmazonServiceException unmarshall(JsonErrorResponse error) throws Exception { ; "PutItem succeeded: " + table.getItem("year", year, "title", title).
Read more >
com.amazonaws.services.dynamodbv2.model. ...
putItem (request); return item; } catch (ConditionalCheckFailedException e) { throw new TransactionException("Failed to create new transaction with id " + ...
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