Moto: Unable to create dynamodb table

Created on 24 Jun 2020  路  4Comments  路  Source: spulec/moto

I'm new to moto. I was able to use moto with S3 without hassle. That was seamless. But I can't figure out this.

Steps to reproduce

pip install moto. The latest via pip is 1.3.14

from moto import mock_dynamodb

@mock_dynamodb
def test_get_latest_price():
    table_name = 'fake-price-table'

    # create a fake table to write to
    client = boto3.client('dynamodb', region_name='ap-southeast-2')
    response = client.create_table(
        TableName=table_name,
        AttributeDefinitions=[
            {
                'AttributeName': 'regionid',
                'AttributeType': 'S'
            },
            {
                'AttributeName': 'time_made',
                'AttributeType': 'N'
            },
        ],
        KeySchema=[
            {
                'AttributeName': 'regionid',
                'KeyType': 'HASH'
            },
            {
                'AttributeName': 'time_made',
                'KeyType': 'RANGE'
            },
        ],
        BillingMode='PAY_PER_REQUEST'
    )

Expected Result

Code executes successfully

Actual result

Traceback (most recent call last):
  File "dynamo.py", line 114, in <module>
    test_get_latest_price()
  File "/home/ec2-user/.local/lib/python3.6/site-packages/moto/core/models.py", line 88, in wrapper
    result = func(*args, **kwargs)
  File "dynamo.py", line 66, in test_get_latest_price
    BillingMode='PAY_PER_REQUEST'
  File "/home/ec2-user/.local/lib/python3.6/site-packages/botocore/client.py", line 316, in _api_call
    return self._make_api_call(operation_name, kwargs)
  File "/home/ec2-user/.local/lib/python3.6/site-packages/botocore/client.py", line 622, in _make_api_call
    operation_model, request_dict, request_context)
  File "/home/ec2-user/.local/lib/python3.6/site-packages/botocore/client.py", line 641, in _make_request
    return self._endpoint.make_request(operation_model, request_dict)
  File "/home/ec2-user/.local/lib/python3.6/site-packages/botocore/endpoint.py", line 102, in make_request
    return self._send_request(request_dict, operation_model)
  File "/home/ec2-user/.local/lib/python3.6/site-packages/botocore/endpoint.py", line 137, in _send_request
    success_response, exception):
  File "/home/ec2-user/.local/lib/python3.6/site-packages/botocore/endpoint.py", line 256, in _needs_retry
    caught_exception=caught_exception, request_dict=request_dict)
  File "/home/ec2-user/.local/lib/python3.6/site-packages/botocore/hooks.py", line 356, in emit
    return self._emitter.emit(aliased_event_name, **kwargs)
  File "/home/ec2-user/.local/lib/python3.6/site-packages/botocore/hooks.py", line 228, in emit
    return self._emit(event_name, kwargs)
  File "/home/ec2-user/.local/lib/python3.6/site-packages/botocore/hooks.py", line 211, in _emit
    response = handler(**kwargs)
  File "/home/ec2-user/.local/lib/python3.6/site-packages/botocore/retryhandler.py", line 183, in __call__
    if self._checker(attempts, response, caught_exception):
  File "/home/ec2-user/.local/lib/python3.6/site-packages/botocore/retryhandler.py", line 251, in __call__
    caught_exception)
  File "/home/ec2-user/.local/lib/python3.6/site-packages/botocore/retryhandler.py", line 269, in _should_retry
    return self._checker(attempt_number, response, caught_exception)
  File "/home/ec2-user/.local/lib/python3.6/site-packages/botocore/retryhandler.py", line 317, in __call__
    caught_exception)
  File "/home/ec2-user/.local/lib/python3.6/site-packages/botocore/retryhandler.py", line 223, in __call__
    attempt_number, caught_exception)
  File "/home/ec2-user/.local/lib/python3.6/site-packages/botocore/retryhandler.py", line 359, in _check_caught_exception
    raise caught_exception
  File "/home/ec2-user/.local/lib/python3.6/site-packages/botocore/endpoint.py", line 197, in _do_get_response
    responses = self._event_emitter.emit(event_name, request=request)
  File "/home/ec2-user/.local/lib/python3.6/site-packages/botocore/hooks.py", line 356, in emit
    return self._emitter.emit(aliased_event_name, **kwargs)
  File "/home/ec2-user/.local/lib/python3.6/site-packages/botocore/hooks.py", line 228, in emit
    return self._emit(event_name, kwargs)
  File "/home/ec2-user/.local/lib/python3.6/site-packages/botocore/hooks.py", line 211, in _emit
    response = handler(**kwargs)
  File "/home/ec2-user/.local/lib/python3.6/site-packages/moto/core/models.py", line 272, in __call__
    request, request.url, request.headers
  File "/home/ec2-user/.local/lib/python3.6/site-packages/moto/core/responses.py", line 197, in dispatch
    return cls()._dispatch(*args, **kwargs)
  File "/home/ec2-user/.local/lib/python3.6/site-packages/moto/core/responses.py", line 295, in _dispatch
    return self.call_action()
  File "/home/ec2-user/.local/lib/python3.6/site-packages/moto/dynamodb/responses.py", line 30, in call_action
    response = getattr(self, endpoint)()
  File "/home/ec2-user/.local/lib/python3.6/site-packages/moto/dynamodb/responses.py", line 64, in create_table
    hash_key = key_schema["HashKeyElement"]
TypeError: list indices must be integers or slices, not str

Notes

  • When I remove the mock_dynamodb decorator and do a real API call, it works
  • Issue #3066 sounds related, but actually that's about secondary indexes, which I'm not using here
debugging

All 4 comments

Hi @mlda065, the @mock_dynamodb refers to an old version of the DynamoDB API.

Can you try the same code with mock_dynamodb2? Your test looks fine, so I imagine that should work

Oh, thanks.

I was wondering what 1 vs 2 was.

I'll give that a try.

In the meantime, may I suggest modifying the documentation to explain the difference?

I assumed that dynamodb2 was for boto3.client('dynamodb2') or something.

Good call @mdavis-xyz - I've updated the README to explain the difference between the two.

is it working now?

Yes, that's clearer now.

Was this page helpful?
0 / 5 - 0 ratings