我在尝试上传到 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 的响应中绝对没有小数。我已经尝试了在堆栈溢出上找到的几乎所有建议,但没有成功。任何帮助将不胜感激!
我在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
这将允许浮点数的不精确和圆角表示!希望这对将来的其他人有帮助:)
我知道您提到在您的回复中没有找到任何小数点,但这适用于那些实际上有类似情况的人。当我搜索该错误代码时,我偶然发现了这个答案。
我传递给 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