& quot; errorMessage&":& quot; [< class' decimal.Inexact' amp;< class' decimal.Rounded& #39;&]&“,同时更新DynamoDb [英] "errorMessage": "[<class 'decimal.Inexact'>, <class 'decimal.Rounded'>]", While updating DynamoDb

查看:118
本文介绍了& quot; errorMessage&":& quot; [< class' decimal.Inexact' amp;< class' decimal.Rounded& #39;&]&“,同时更新DynamoDb的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

代码在下面

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)

在更新dynamodb中的键时,出现以下错误

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

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

如果我将8.3更改为8,我的代码运行正常

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:")``` 

推荐答案

问题在于DynamoDB的浮点数表示形式与Python的表示形式不同:

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

  1. DynamoDB用十进制表示形式表示浮点数.因此,"8.3"可以准确地表示-不会四舍五入或不精确.
  2. Python作为传统的base-2表示形式,因此它不能完全表示8.3. 8.3实际上表示为8.3000000000000007105,并且已知是不精确的(python不知道您到底打算使用哪个数字).
  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).

SDK知道浮点8.3不精确,因此拒绝使用它.

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

解决方案是按预期使用Decimal类:应使用字符串参数而不是浮点数构造它.即,使用Decimal("8.3")(请注意引号), Decimal(8.3).

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).

在上面的代码中,修复此问题很简单,就像将8.3改为带引号的"8.3"一样.

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

那是最好的方法.另一种不太好用的方法是执行Decimal(str(8.3))),但要为可能出现的数字不精确表示做准备.此外,使用字符串创建Decimal允许您创建Python根本不支持的数字.例如,Decimal("3.1415926535897932384626433832795028841")将为您提供38位十进制数字的精度(DynamoDB支持的最大值),这是您在Python浮点数中无法做到的.

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.

这篇关于&amp; quot; errorMessage&amp;&quot;:&amp; quot; [&lt; class&amp;#39; decimal.Inexact&amp;#39; amp;&lt; class&amp;#39; decimal.Rounded&amp; #39;&amp;]&amp;“,同时更新DynamoDb的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆