Moto: get_items errors with mock dynamodb2 decorator for moto

Created on 21 Jun 2017  路  5Comments  路  Source: spulec/moto

Hi,
But when I am trying to get the table items with the help of get_item(). As it throws
botocore.exceptions.ClientError: An error occurred (ValidationException)
Please help to get out of this issue

Below packages which i have imported in my script
import os, json, sys, boto3, time
from boto3.session import Session
from moto import mock_dynamodb2
from boto3.dynamodb.conditions import Key, Attr

#####Code Snippet

    # Print out some data about the table.
    filters = event_data['filters']
    key = {'deviceID': filters['device_id']}
    print (key)
    try:
        response = table.get_item(Key=key)
        print("this is response",response) 
    except Exception as e:
        logger.exception(e)

(Pdb) key
{'deviceID': '2304'}

(Pdb) response = table.get_item(Key=key)
INFO:boto3.resources.action:Calling dynamodb:get_item with {'TableName': 'intelli_temp_mon_assets_dev', 'Key': {'deviceID': '2304'}}
botocore.exceptions.ClientError: An error occurred (ValidationException) when calling the GetItem operation:*

####Complete Code below:

import os, json, sys, boto3, time
from boto3.session import Session
import logging
from moto import mock_dynamodb2
from MyDynamodbClass import *

from boto3.dynamodb.conditions import Key, Attr
logging.basicConfig()
logger = logging.getLogger()
logger.setLevel(logging.INFO)

logger.info("SUCCESS: Connection to DATABASE and SNS instance succeeded")

class Post_Lambda(object):

Test Class. All your test functonality

def main():
fileDir = os.path.dirname(os.path.realpath('file'))
event_file = os.path.join(fileDir, 'mock_event.json')
with open(event_file) as json_data:
event_data = json.load(json_data)

with mock_dynamodb2():
    session = Session(aws_access_key_id='<YOUR ACCESS KEY ID>',
                      aws_secret_access_key='<YOUR SECRET KEY>',
                      region_name= 'us-east-1')
    # Get the service resource
    dynamodb = session.resource('dynamodb')

    # Create the DynamoDB table.
    table = dynamodb.create_table(
        TableName='intelli_temp_mon_assets_dev',
        KeySchema=[
            {
                'AttributeName': 'device_id',
                'KeyType': 'HASH'
            }
        ],
        AttributeDefinitions=[
            {
                'AttributeName': 'device_id',
                'AttributeType': 'S'
            }
        ],
        ProvisionedThroughput={
            'ReadCapacityUnits': 5,
            'WriteCapacityUnits': 5
        }
    )
    # Wait until the table exists.
    table.meta.client.get_waiter('table_exists').wait(TableName='intelli_temp_mon_assets_dev')
    table.put_item(
           Item={
                'device_id': '2004',
                'alarm_level': 'low',
                'alarms': '100',
                'category': 'Fridge',
                'device-status': 'false',
                'current_temp': '28.50',
                "measure_unit":  'C',
                "siteID": '712',
                "locationID": 'location2',
                "model_type": 'Eskimo1890'
            }
    )
    table.put_item(
        Item={
                'device_id': '2304',
                'alarm_level': 'high',
                'alarms': '200',
                'category': 'Fridge',
                'device-status': 'true', 
                'current_temp': '38.50',
                "measure_unit":  'C',
                "siteID": '863',
                "locationID": 'location1',
                "model_type": 'Eskimo1990'
            }
    )
    # Print out some data about the table.
    filters = event_data['filters']
    key = {'deviceID': filters['device_id']}
    print (key)
    try:
        response = table.get_item(Key=key)
        print("this is response",response) 
    except Exception as e:
        logger.exception(e)

    logger.info("Your code logic")
    data={}
    import pdb; pdb.set_trace()
    print(table.item_count)
    # foo = Feature.myfun()
    foo = lambda_handler(None, None)
    print("You have to assert this response %s " %(foo))

if __name__ == '__main__':
main()

Fails with Stack trace

$ python mock_device_details.py
INFO:root:SUCCESS: Connection to DATABASE and SNS instance succeeded
INFO:boto3.resources.action:Calling dynamodb:create_table with {'TableName': 'intelli_temp_mon_assets_dev', 'AttributeDefinitions': [{'AttributeName': 'device_id', 'AttributeType': 'S'}], 'KeySchema': [{'AttributeName': 'device_id', 'KeyType': 'HASH'}], 'ProvisionedThroughput': {'ReadCapacityUnits': 5, 'WriteCapacityUnits': 5}}
INFO:boto3.resources.action:Calling dynamodb:put_item with {'TableName': 'intelli_temp_mon_assets_dev', 'Item': {'locationID': 'location2', 'alarm_level': 'low', 'alarms': '100', 'measure_unit': 'C', 'current_temp': '28.50', 'model_type': 'Eskimo1890', 'siteID': '712', 'category': 'Fridge', 'device_id': '2004', 'device-status': 'false'}}
INFO:boto3.resources.action:Calling dynamodb:put_item with {'TableName': 'intelli_temp_mon_assets_dev', 'Item': {'locationID': 'location1', 'alarm_level': 'high', 'alarms': '200', 'measure_unit': 'C', 'current_temp': '38.50', 'model_type': 'Eskimo1990', 'siteID': '863', 'category': 'Fridge', 'device_id': '2304', 'device-status': 'true'}}
INFO:boto3.resources.action:Calling dynamodb:get_item with {'TableName': 'intelli_temp_mon_assets_dev', 'Key': {'deviceID': '2304'}}
ERROR:root:An error occurred (ValidationException) when calling the GetItem operation:
Traceback (most recent call last):
File "mock_device_details.py", line 93, in main
response = table.get_item(Key=key)
File "C:\Python33\lib\site-packages\boto3\resourcesfactory.py", line 520, in do_action
response = action(self, *args, kwargs)
File "C:\Python33\lib\site-packages\boto3\resources\action.py", line 83, in call
response = getattr(parent.meta.client, operation_name)(
params)
File "C:\Python33\lib\site-packages\botocore\client.py", line 253, in _api_call
return self._make_api_call(operation_name, kwargs)
File "C:\Python33\lib\site-packages\botocore\client.py", line 557, in _make_api_call
raise error_class(parsed_response, operation_name)
botocore.exceptions.ClientError: An error occurred (ValidationException) when calling the GetItem operation:
INFO:root:Your code logic
{'deviceID': '2304'}

bug

Most helpful comment

I'm working on moto 1.3.3 and am still running into this issue. Any suggested fixes or workaround?

My function call
elem = table.get_item( Key={ "KeyName":entry } )

I'm trying to build a mockup table via a set of pytest fixtures and to pass the entire context in.
So far the context seems to load properly, but I keep hitting this ValidationError when I try to invoke the get_item endpoint and a ConditionalCheckFailedException when trying to invoke the delete_item endpoint with no conditions. TBH I can't tell whether this is a bug with moto I'm dealing with, or whether my mockup environment did not get properly passed in/added to the context manager.

UPDATE:
I tried stepping through my code and ran into what seemed to be the same issue after creating the table in my original test fixture:
Fixture code -

@pytest.fixture(scope="session")
def mock_dynamo_hook():
-> m = mock_dynamodb2()
-> m.start()
-> template = dynamo_template()
-> (mock_table,user_list) = moto_dynamo(template,m)
-> print (mock_table.table_status)
-> pdb.set_trace()
-> yield (m, mock_table, user_list)
-> print ("Tearing down Mockup environment.")
-> m.stop()

(Where -> is a place-holder for an indent)
Running the tests I found the following:

yield (m, mock_table, user_list)
(Pdb) mock_table.load()
(Pdb) mock_table.item_count
30
(Pdb) mock_table.query(IndexName='EmailAddress',Select='ALL_ATTRIBUTES')
* UnboundLocalError: local variable 'hash_key' referenced before assignment

All 5 comments

Any word on a possible work-around?

hi sorry for the delayed response !!!
The above issue occurs till moto 1.1.25 release. Later on i have updated moto library with moto 1.2.0 in the month of march. Hence my issue got resolved and it supports all the methods example: table.get_item(Key=key) and other usage as well..
Thanks for the support :)

I'm working on moto 1.3.3 and am still running into this issue. Any suggested fixes or workaround?

My function call
elem = table.get_item( Key={ "KeyName":entry } )

I'm trying to build a mockup table via a set of pytest fixtures and to pass the entire context in.
So far the context seems to load properly, but I keep hitting this ValidationError when I try to invoke the get_item endpoint and a ConditionalCheckFailedException when trying to invoke the delete_item endpoint with no conditions. TBH I can't tell whether this is a bug with moto I'm dealing with, or whether my mockup environment did not get properly passed in/added to the context manager.

UPDATE:
I tried stepping through my code and ran into what seemed to be the same issue after creating the table in my original test fixture:
Fixture code -

@pytest.fixture(scope="session")
def mock_dynamo_hook():
-> m = mock_dynamodb2()
-> m.start()
-> template = dynamo_template()
-> (mock_table,user_list) = moto_dynamo(template,m)
-> print (mock_table.table_status)
-> pdb.set_trace()
-> yield (m, mock_table, user_list)
-> print ("Tearing down Mockup environment.")
-> m.stop()

(Where -> is a place-holder for an indent)
Running the tests I found the following:

yield (m, mock_table, user_list)
(Pdb) mock_table.load()
(Pdb) mock_table.item_count
30
(Pdb) mock_table.query(IndexName='EmailAddress',Select='ALL_ATTRIBUTES')
* UnboundLocalError: local variable 'hash_key' referenced before assignment

the same issue with moto = "==1.3.16"
self = , operation_name = 'GetItem', api_params = {'AttributesToGet': ['ARN'], 'Key': {'Role': '000000000001-role'}, 'TableName': 'Roles'}

Hi @vsuzdaltsev, please open a new issue for this if it's still a problem. The DynamoDB implementation has improved quite a bit since the original problem, so this is probably unrelated.

Please provide a sample unit test in the new issue, so we can reproduce it.

Was this page helpful?
0 / 5 - 0 ratings