Skip to content

How can I store 30.40 in DynamoDb? #665

@jonapich

Description

@jonapich

It's the end of the day, maybe i'm not seeing this clearly... But I am unable to store simple float values without adding some arcane magic to the mix.

Using .put_item on a Table resource that contains a float:

item = {'name': 'testing_row', 'foo': 30.40}
table.put_item(Item=item)
>> TypeError: Float types are not supported. Use Decimal types instead.

The same thing, using Decimal:

item = {'name': 'testing_row', 'foo': Decimal(30.40)}
table.put_item(Item=item)
>> Inexact: None

This last one should have gone through, no? The stack trace is this:

>       table.put_item(Item=item)

E:\Projects\Repos\tests\test_dynamodb.py:9: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
C:\Python27\lib\site-packages\boto3\resources\factory.py:518: in do_action
    response = action(self, *args, **kwargs)
C:\Python27\lib\site-packages\boto3\resources\action.py:83: in __call__
    response = getattr(parent.meta.client, operation_name)(**params)
C:\Python27\lib\site-packages\botocore\client.py:258: in _api_call
    return self._make_api_call(operation_name, kwargs)
C:\Python27\lib\site-packages\botocore\client.py:524: in _make_api_call
    api_params, operation_model, context=request_context)
C:\Python27\lib\site-packages\botocore\client.py:574: in _convert_to_request_dict
    params=api_params, model=operation_model, context=context)
C:\Python27\lib\site-packages\botocore\hooks.py:227: in emit
    return self._emit(event_name, kwargs)
C:\Python27\lib\site-packages\botocore\hooks.py:210: in _emit
    response = handler(**kwargs)
C:\Python27\lib\site-packages\boto3\dynamodb\transform.py:197: in inject_attribute_value_input
    'AttributeValue')
C:\Python27\lib\site-packages\boto3\dynamodb\transform.py:252: in transform
    model, params, transformation, target_shape)
C:\Python27\lib\site-packages\boto3\dynamodb\transform.py:259: in _transform_parameters
    model, params, transformation, target_shape)
C:\Python27\lib\site-packages\boto3\dynamodb\transform.py:274: in _transform_structure
    target_shape)
C:\Python27\lib\site-packages\boto3\dynamodb\transform.py:259: in _transform_parameters
    model, params, transformation, target_shape)
C:\Python27\lib\site-packages\boto3\dynamodb\transform.py:283: in _transform_map
    params[key] = transformation(value)
C:\Python27\lib\site-packages\boto3\dynamodb\types.py:103: in serialize
    return {dynamodb_type: serializer(value)}
C:\Python27\lib\site-packages\boto3\dynamodb\types.py:204: in _serialize_n
    number = str(DYNAMODB_CONTEXT.create_decimal(value))
C:\Python27\lib\decimal.py:3938: in create_decimal
    return d._fix(self)
C:\Python27\lib\decimal.py:1712: in _fix
    context._raise_error(Inexact)

I can make it go through if I use the string trick in the Decimal constructor:

item = {'name': 'testing_row', 'foo': Decimal('30.40')}
table.put_item(Item=item)

Having done that, using AWS's dashboard to look into the table, I can see a number type with the value of 30.4 but then I cannot assert its value in my tests:

item = table.get_item(Key={'name': 'testing_row'})['Item']['foo']
assert item == 30.4
>> False

This seems to work:

assert float(item) == 30.4

So how's this supposed to work exactly? Is it expected that I must 1) provide a string to decimal and 2) convert back to float myself for equality to work properly?

Metadata

Metadata

Assignees

No one assigned

    Labels

    dynamodbfeature-requestThis issue requests a feature.needs-major-versionCan only be considered for the next major releasep2This is a standard priority issue

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions