4 回答

TA貢獻(xiàn)1804條經(jīng)驗(yàn) 獲得超8個(gè)贊
編輯:
該convert_decimal()函數(shù)將在復(fù)雜的 dict 結(jié)構(gòu)中執(zhí)行 Decimal 到 Decimal128 的轉(zhuǎn)換:
import simplejson as json
from pymongo import MongoClient
from decimal import Decimal
from bson.decimal128 import Decimal128
def convert_decimal(dict_item):
# This function iterates a dictionary looking for types of Decimal and converts them to Decimal128
# Embedded dictionaries and lists are called recursively.
if dict_item is None: return None
for k, v in list(dict_item.items()):
if isinstance(v, dict):
convert_decimal(v)
elif isinstance(v, list):
for l in v:
convert_decimal(l)
elif isinstance(v, Decimal):
dict_item[k] = Decimal128(str(v))
return dict_item
db = MongoClient()['mydatabase']
json_string = '{"A" : {"B" : [{"C" : {"Horz" : 0.181665435,"Vert" : 0.178799435}}]}}'
json_dict = json.loads(json_string, use_decimal=True)
db.this_collection.insert_one(convert_decimal(json_dict))
print(db.this_collection.find_one())
給出:
{'_id': ObjectId('5ea743aa297c9ccd52d33e05'), 'A': {'B': [{'C': {'Horz': Decimal128('0.181665435'), 'Vert': Decimal128('0.178799435')}}]}}
原來(lái)的:
要將小數(shù)轉(zhuǎn)換為 MongoDB 滿意的 Decimal128,請(qǐng)將其轉(zhuǎn)換為字符串,然后再轉(zhuǎn)換為 Decimal128。此代碼段可能會(huì)有所幫助:
from pymongo import MongoClient
from decimal import Decimal
from bson.decimal128 import Decimal128
db = MongoClient()['mydatabase']
your_number = Decimal('234.56')
your_number_128 = Decimal128(str(your_number))
db.mycollection.insert_one({'Number': your_number_128})
print(db.mycollection.find_one())
給出:
{'_id': ObjectId('5ea6ec9b52619c7b39b851cb'), 'Number': Decimal128('234.56')}

TA貢獻(xiàn)1821條經(jīng)驗(yàn) 獲得超5個(gè)贊
Pymongo 無(wú)法識(shí)別Decimal
- 這就是您收到錯(cuò)誤的原因。
正確的 pymongo 插入是coll.insert_one({"number1": Decimal128('8.916')})
.
您還需要導(dǎo)入 -from bson import Decimal128
現(xiàn)在,如果您想在不更改Decimal
為 Decimal128 的情況下處理您的 JSON 文件,您可以修改導(dǎo)入語(yǔ)句。
from bson import Decimal128 as Decimal coll.insert_one({"number1": Decimal('8.916')})

TA貢獻(xiàn)1859條經(jīng)驗(yàn) 獲得超6個(gè)贊
我建議只添加一個(gè)編解碼器以在插入時(shí)自動(dòng)轉(zhuǎn)換數(shù)據(jù)類型。如果您遞歸地更改數(shù)據(jù)類型以使用 Decimal128 對(duì)象,您可能會(huì)破壞與現(xiàn)有代碼的兼容性。
您可以按照教程在此處的 pymongo 文檔中創(chuàng)建一個(gè)簡(jiǎn)單的 decimal.Decimal 編解碼器

TA貢獻(xiàn)1744條經(jīng)驗(yàn) 獲得超4個(gè)贊
from bson.decimal128 import Decimal128, create_decimal128_context
from decimal import localcontext
decimal128_ctx = create_decimal128_context()
with localcontext(decimal128_ctx) as ctx:
horiz_val = Decimal128(ctx.create_decimal("0.181665435"))
vert_val = Decimal128(ctx.create_decimal("0.178799435"))
doc = { 'A': { 'B': [ { 'C': { 'Horiz': horiz_val, 'Vert': vert_val } } ] } }
result = collection.insert_one(doc)
# result.inserted_id
pprint.pprint(list(collection.find()))
[ {'A': {'B': [{'C': {'Horiz': Decimal128('0.181665435'),
'Vert': Decimal128('0.178799435')}}]},
'_id': ObjectId('5ea79adb915cbf3c46f5d4ae')} ]
筆記:
PyMongo 的decimal128 - 支持 BSON Decimal128
Python 的十進(jìn)制模塊 提供對(duì)十進(jìn)制浮點(diǎn)運(yùn)算的支持。
來(lái)自 PyMongo 的 decimal128 文檔:
為確保計(jì)算結(jié)果始終可以存儲(chǔ)為 BSON Decimal128,請(qǐng)使用返回的上下文
create_decimal128_context()
(注意:如上面的示例代碼所示)。
添加回答
舉報(bào)