Boto DynamoDb - JSONResponseError: 400 Bad Request - really weird behaviour
Question: I'm working with the Boto DynamoDb2 API and I'm experiencing something really
strange. First off, I'm using an IAM Role for authentication and the code I'm
about to show is being run on an EC2 instance with the attached Role. The Role
has full administrative permissions and I'm positive the issue isn't related
to permissions.

I have code that creates a table and then adds an item to that table. However,
the first time I `put_item`, it throws an exception, but it works the next
time right afterwards. Here's a dump from my python interpreter:

    
    
    Python 2.7.10 (default, Aug 11 2015, 23:39:10) 
    [GCC 4.8.3 20140911 (Red Hat 4.8.3-9)] on linux2
    Type "help", "copyright", "credits" or "license" for more information.
    >>> import boto.dynamodb2
    >>> from boto.dynamodb2.table import Table
    >>> from boto.dynamodb2.fields import HashKey
    >>> from boto.dynamodb2.types import NUMBER
    >>> 
    >>> table = Table.create('myTablse',
    ...     schema=[HashKey('index', data_type=NUMBER)],
    ...     connection=boto.dynamodb2.connect_to_region('eu-west-1'))
    >>> 
    >>> table.put_item(data={
    ...     'index': 4,
    ...     'sequence': 'sdfsdf34rfdsa'
    ... })
    Traceback (most recent call last):
      File "<stdin>", line 3, in <module>
      File "/home/ec2-user/fyp/venv/local/lib/python2.7/site-packages/boto/dynamodb2/table.py", line 821, in put_item
        return item.save(overwrite=overwrite)
      File "/home/ec2-user/fyp/venv/local/lib/python2.7/site-packages/boto/dynamodb2/items.py", line 455, in save
        returned = self.table._put_item(final_data, expects=expects)
      File "/home/ec2-user/fyp/venv/local/lib/python2.7/site-packages/boto/dynamodb2/table.py", line 835, in _put_item
        self.connection.put_item(self.table_name, item_data, **kwargs)
      File "/home/ec2-user/fyp/venv/local/lib/python2.7/site-packages/boto/dynamodb2/layer1.py", line 1510, in put_item
        body=json.dumps(params))
      File "/home/ec2-user/fyp/venv/local/lib/python2.7/site-packages/boto/dynamodb2/layer1.py", line 2842, in make_request
        retry_handler=self._retry_handler)
      File "/home/ec2-user/fyp/venv/local/lib/python2.7/site-packages/boto/connection.py", line 954, in _mexe
        status = retry_handler(response, i, next_sleep)
      File "/home/ec2-user/fyp/venv/local/lib/python2.7/site-packages/boto/dynamodb2/layer1.py", line 2885, in _retry_handler
        data)
    boto.exception.JSONResponseError: JSONResponseError: 400 Bad Request
    {u'message': u'Requested resource not found', u'__type': u'com.amazonaws.dynamodb.v20120810#ResourceNotFoundException'}
    >>> table.put_item(data={
    ...     'index': 4,
    ...     'sequence': 'sdfsdf34rfdsa'
    ... })
    True
    >>> 
    

Can someone tell me what's going on here?


Answer: Figured this out. When you submit the CreateTable API call and it returns a
200, that doesn't mean that the table is created yet or ready to use for that
matter as everything seems to happen asynchronously.

So basically, you need to wait until the table is ready before you can add
items to it. Here is my solution:

    
    
     con = boto.dynamodb2.connect_to_region('eu-west-1')
    
    table = Table.create('myTables',
        schema=[HashKey('index', data_type=NUMBER)],
        connection=con)
    
    while True:
        try:
            r=con.describe_table('myTables')
            if r and r['Table']['TableStatus'] == 'ACTIVE':
                break
        except JSONResponseError, e:
            if 'resource not found' in e.message:
                pass
            else:
                raise
        time.sleep(1)
    
    table.put_item(data={
        'index': 4,
        'sequence': 'sdfsdf34rfdsa'
    })
    

Hope this helps someone else!

