为了账号安全,请及时绑定邮箱和手机立即绑定

"errorMessage": "[<class 'decimal.Inexact'>

"errorMessage": "[<class 'decimal.Inexact'>

喵喵时光机 2023-03-22 16:10:21
代码如下import jsonfrom decimal import Decimalfrom pprint import pprintimport boto3def 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 responsedef 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 中更新密钥时出现以下错误  "errorMessage": "[<class 'decimal.Inexact'>, <class 'decimal.Rounded'>]",  "errorType": "Inexact",如果我更改8.3为8我的代码工作正常update_response = update_movie(        "Rush", 2013, 8.3, "Car show",        ["Daniel", "Chris", "Olivia"])    print("Update movie succeeded:")``` 
查看完整描述

3 回答

?
慕丝7291255

TA贡献1859条经验 获得超6个赞

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

  1. DynamoDB 以十进制表示浮点数。所以“8.3”可以精确表示——没有四舍五入或不精确。

  2. Python 使用传统的 base-2 表示法,因此它不能准确地表示 8.3。8.3 实际上表示为 8.3000000000000007105 并且已知是不精确的(python 不知道你最后想要的数字)。

SDK 知道浮点数 8.3 不准确,并拒绝使用它。

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

在您上面的代码中,解决这个问题就像将 8.3 更改为“8.3”(带引号)一样简单。

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


查看完整回答
反对 回复 2023-03-22
?
慕田峪9158850

TA贡献1794条经验 获得超7个赞

我也遇到了这个问题。我发现该方法的问题Decimal(str(my_float))是它str(my_float)只会保留 16 位有效数字,这对我们来说还不够。


相反,您可以Decimal在 new 下构造对象decimal.Context,这不会引发[<class 'decimal.Inexact'>, <class 'decimal.Rounded'>]错误,因为它没有设置这些陷阱:


from decimal import Decimal, Context


my_float = 8.3


# 1. Create the context. DynamoDB supports up to 38

# digits of precision.

ctx = Context(prec=38)


# 2. Create the decimal from within the new context, which

# will not raise the Inexact/Rounded error.

my_decimal = ctx.create_decimal_from_float(my_float)


# 3. Save `my_decimal` to DynamoDB without error, and with

# maximum precision preserved.


查看完整回答
反对 回复 2023-03-22
?
潇潇雨雨

TA贡献1833条经验 获得超4个赞

一旦尝试这个:


ExpressionAttributeValues={

            ':r': Decimal(str(rating)),

            ':p': plot,

            ':a': actors

        },


查看完整回答
反对 回复 2023-03-22
  • 3 回答
  • 0 关注
  • 161 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号