3 回答

TA貢獻1859條經驗 獲得超6個贊
問題在于 DynamoDB 的浮點數表示與 Python 的不同:
DynamoDB 以十進制表示浮點數。所以“8.3”可以精確表示——沒有四舍五入或不精確。
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 浮點數中無法做到的。

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.

TA貢獻1833條經驗 獲得超4個贊
一旦嘗試這個:
ExpressionAttributeValues={
':r': Decimal(str(rating)),
':p': plot,
':a': actors
},
添加回答
舉報