Dynamodb - 不精确:[<class 'decimal.Inexact'>,<class 'decimal.Rounded'>]

问题描述 投票:0回答:2

我在尝试上传到 DynamoDb 时遇到了这个错误,完全迷失了方向。我正在尝试将 Shodan API 响应上传到表。

response = [{<nested_JSON>}, {<nested_JSON>}, {<nested_JSON>}]

for i in response:
    test = loads(dumps(item), parse_float=Decimal)
    old_dic_with_decimals = replace_decimals(test)
    new_dict_with_decimals_as_strings = loads(dumps(old_dic_with_decimals))
    dynamodb.table.put_item(Item=new_dict_with_decimals_as_strings)

但我在

put_item
功能上遇到此错误。

[ERROR] Inexact: [<class 'decimal.Inexact'>, <class 'decimal.Rounded'>]

我已经打印了输出,可以确认响应中没有 Decimal 类。这是我将小数转换为字符串的函数:

def replace_decimals(obj):
    if isinstance(obj, list):
        for i in range(len(obj)):
            obj[i] = replace_decimals(obj[i])
        return obj
    elif isinstance(obj, dict):
        for k, v in obj.items():
            obj[k] = replace_decimals(obj[k])
        return obj
    elif isinstance(obj, Decimal):
        ctx = Context(prec=4)
        # In my original code I'm converting to int or float, comment the line above if necessary.
        if obj % 1 == 0:
            my_decimal = ctx.create_decimal_from_float(int(obj))
            obj = str(my_decimal)
            return obj
        else:
            my_decimal = ctx.create_decimal_from_float(float(obj))
            obj = str(my_decimal)
            return obj
    else:
        return obj

我不明白为什么 Dynamodb 会抛出这个错误。我尝试发送到 Dynamodb 的响应中绝对没有小数。我已经尝试了在堆栈溢出上找到的几乎所有建议,但没有成功。任何帮助将不胜感激!

python amazon-dynamodb boto3
2个回答
1
投票

我在github上找到这个猴子补丁后解决了这个问题:https://gist.github.com/lbenitez000/85fb43e40a7839e13405

基本上你必须添加这个:

# Monkey patch Decimal's default Context to allow 
# inexact and rounded representation of floats
import decimal
from boto.dynamodb.types import DYNAMODB_CONTEXT
# Inhibit Inexact Exceptions
DYNAMODB_CONTEXT.traps[decimal.Inexact] = 0
# Inhibit Rounded Exceptions
DYNAMODB_CONTEXT.traps[decimal.Rounded] = 0

这将允许浮点数的不精确和圆角表示!希望这对将来的其他人有帮助:)


0
投票

我知道您提到在您的回复中没有找到任何小数点,但这适用于那些实际上有类似情况的人。当我搜索该错误代码时,我偶然发现了这个答案。

我传递给 dynamoDB 的值是 185.1851851851852,类型为 float。我用

将其转换为十进制
from decimal import Decimal
Decimal(185.1851851851852)

但问题仍然存在。所以我脑子里突然想到要减少小数位数(无论如何我都应该有XD),这就成功了。 Python 十进制常见问题解答

from decimal import Decimal
TWOPLACES = Decimal(10) ** -2   # same as Decimal('0.01')
Decimal(185.1851851851852).quantize(TWOPLACES)
# 185.19
© www.soinside.com 2019 - 2024. All rights reserved.