“errorMessage”: “[<class 'decimal.Inexact'>, <class 'decimal.Rounded'>]”, While updating DynamoDb

倖福魔咒の 提交于 2020-07-27 03:29:40

问题


Code is below

import json
from decimal import Decimal
from pprint import pprint
import boto3


def update_movie(title, year, rating=None, plot=None, actors=None, dynamodb=None):
    if not dynamodb:
        dynamodb = boto3.resource('dynamodb')

    table = dynamodb.Table('Movies')

    response = table.update_item(
        Key={
            'year': year,
            'title': title
        },
        UpdateExpression="set info.rating=:r, info.plot=:p, info.actors=:a",
        ExpressionAttributeValues={
            ':r': Decimal(rating),
            ':p': plot,
            ':a': actors
        },
        ReturnValues="UPDATED_NEW"
    )
    return response


def lambda_handler(event, context):
    update_response = update_movie(
        "Rush", 2013, 8.3, "Car show",
        ["Daniel", "Chris", "Olivia"])
    print("Update movie succeeded:")
    pprint(update_response, sort_dicts=False)

While updating a key in the dynamodb i got the error below

  "errorMessage": "[<class 'decimal.Inexact'>, <class 'decimal.Rounded'>]",
  "errorType": "Inexact",

If i am changing 8.3 to 8 My code is working fine

update_response = update_movie(
        "Rush", 2013, 8.3, "Car show",
        ["Daniel", "Chris", "Olivia"])
    print("Update movie succeeded:")``` 

回答1:


The problem is that DynamoDB's representation of floating-point numbers is different from Python's:

  1. DynamoDB represents floating point numbers with a decimal representation. So "8.3" can be represented exactly - with no rounding or inexactness.
  2. Python uses, as traditional, base-2 representation, so it can't represent 8.3 exactly. 8.3 is actually represented as 8.3000000000000007105 and is known to be inexact (python doesn't know which digits you intended at the very end).

The SDK knows the floating-point 8.3 is inexact, and refuses to use it.

The solution is to use the Decimal class as intended: It should be constructed with a string parameter, not a floating-point one. I.e., use Decimal("8.3") (note the quotes), not Decimal(8.3).

In your code above fixing this is as trivial as changing 8.3 to "8.3", with quotes.

That's the best approach. The other, not as good, approach is to do Decimal(str(8.3))), but be prepared for the potential of inexact representation of the numbers. Moreover, creating a Decimal with a string allows you to create numbers which are simply not supported in Python. For example, Decimal("3.1415926535897932384626433832795028841") will get you 38 decimal digits of precision (the maximum supported by DynamoDB) - something you cannot do in Python floating point.




回答2:


once try this:

ExpressionAttributeValues={
            ':r': Decimal(str(rating)),
            ':p': plot,
            ':a': actors
        },


来源:https://stackoverflow.com/questions/63026648/errormessage-class-decimal-inexact-class-decimal-rounded-while

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!