Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Precision of floating point DynamoDB attributes #137

Closed
danielrhodeswarp opened this issue Aug 22, 2013 · 8 comments
Closed

Precision of floating point DynamoDB attributes #137

danielrhodeswarp opened this issue Aug 22, 2013 · 8 comments
Labels
feature-request A feature should be added or improved. guidance Question that needs advice or information.

Comments

@danielrhodeswarp
Copy link

I feel it is important that both the devs and the userland folk are aware of a slight quirk with the DynamoDB Attribute class and factory() method.

Basically, due to line 100 of /src/Aws/DynamoDb/Model/Attribute.php [$attribute = new Attribute((string) $value, Type::NUMBER);] casting a float $value to a string, we have the potential to lose precision of the floating point value.

Because, when you cast a float to a string in PHP it will be a string with max precision of ini_get('precision').

For the time being I have had to hack around this by doing ini_set('precision', $someLargeNumber) before I call $ddbClient->formatAttributes() and what-have-you.

It would be super lovely if the SDK could automagically not lose any precision with the floating point attribute values.

Please see http://www.php.net/manual/en/ini.core.php#ini.precision and http://php.net/manual/en/language.types.float.php

Thanks a lot guys. This SDK is rockin' pretty hard!

@mtdowling
Copy link
Member

Thanks for reminding us that this needs to be documented.

I don't think there is any way to workaround the ini limit enforced by precision. Even if Amazon DynamoDB did not serialize number values in strings and allowed JSON primitives, using json_encode directly with a float can lose precision:

ini_set('precision', 3);
var_export(json_encode(['foo' => 2.12345]));

Outputs: '{"foo":2.12}'

So I think there are a two options:

  1. Increase the precision ini value
  2. Build the request without using the formatAttributes() method and pass the float value in as a string

@jeremeamia
Copy link
Contributor

@danielrhodeswarp
Copy link
Author

Related and possibly of use as a solution!

I've just done some quick messing around, and it does indeed look like printf() and sprintf() do not honour ini_get('precision').

Instead they seem to print the full accuracy of the float in question (ie. 6 digits for microtime(true)).

Interesting...

@danielrhodeswarp
Copy link
Author

To clarify, sprintf() [and etc] seems to default to 6 decimal places but you can specify more - even more than ini_get('precision')

@jeremeamia
Copy link
Contributor

I don't think there is much we can do in the SDK itself to convert floats to strings with the desired precision, but sprintf should help you in your case. I'm going to go ahead and close this. If you come up with any ideas though, let us know.

@waylandzhang
Copy link

Hi Jeremy,

So I can not use the sdk method "PutItem" like this way:


//some json raw data
$row = '{
    "Day": "Monday",
    "UnreadEmails": 42,
    "ItemsOnMyDesk": [
        "Coffee Cup",
        "Telephone",
        {
            "Pens": {
                "Quantity": 3
            }
        }
    ]
}';
// write to DynamoDB
$result = $client->putItem(array(
    'TableName' => 'My_Table',
    'Item' => array(
        'Id'      => array('S' => 'Id000001'),
        'data' => array('M' => $raw),
        ),
    )
);

This seems doesn't working for the current SDK. Do we have to parse each node in the raw json and give something like 'S' => value instead?

Thanks

@jeremeamia
Copy link
Contributor

That will not work. The PHP SDK mirrors the actual API exactly, which requires the types be specified, even for values nested in M and L values. We are discussing ideas in #357 including one I have in this gist. If you have ffedback or ideas you'd like to share, please do so on #357.

@waylandzhang
Copy link

Thank you, that helps a lot.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature-request A feature should be added or improved. guidance Question that needs advice or information.
Projects
None yet
Development

No branches or pull requests

4 participants