2016-12-23 4 views
1

Ich spiele gerade mit dem neuen mongodb-Datentyp NumberDecimal. Ich baue im Allgemeinen wissenschaftliche Apps, die genaue Präzision erfordern (oder so genau wie möglich), also frage ich mich, wie ich es benutzen kann.MongoDB NumberDecimal: nicht unterstützte Operandentypen für +: 'Decimal128' und 'Decimal128'

Eine der Apps, die ich erstelle, ist eine Python-Flask-App, die Daten aus einer Datenbank abruft und verschiedene Berechnungen durchführt. Allerdings, wenn ich ein NumberDecimal von mongodb ziehen (sie NumberDecimal('24.55') sagt) und versucht, einen hinzuzufügen, es fügen Sie es zu einer bson.decimal128.Decimal128 Nummer ich in Python erstellt bekomme ich folgende Fehlermeldung:

TypeError: unsupported operand type(s) for +: 'Decimal128' and 'Decimal128' 

Und wenn ich versuche zu konvertieren NumberDecimal-decimal.Decimal (oder etwas anderes):

TypeError: Cannot convert Decimal128('24.55') to Decimal 

Also ich denke, ich ein paar Fragen: (1) ist es trotzdem, diese NumberDecimal zu irgendetwas zu konvertieren ich in python verwenden kann, (2) wenn nicht, ist dort ein Datentyp Ich kann alle meine anderen Zahlen in die mit 012 kompatibel konvertieren, (3) wenn nicht, scheint mir die einzige Möglichkeit, die ich verwenden kann, serverseitig mit Hilfe des Aggregation-Frameworks (gibt es andere Anwendungsfälle)?

Antwort

2

Es scheint, dass Sie Decimal128-Instanzen in Standard-Python-Dezimalzahlen umwandeln müssen, um sie zu betreiben. Aber Sie sollten das in einem Kontext tun, der von create_decimal128_context, von bson.decimal128 erstellt wurde, um sicherzustellen, dass Ergebnisse später in der Datenbank gespeichert werden können.

>>> from bson.decimal128 import Decimal128, create_decimal128_context 
>>> import decimal 
>>> 
>>> D128_CTX = create_decimal128_context() 
>>> 
>>> with decimal.localcontext(D128_CTX): 
...  d1 = Decimal128('1.23') 
...  d2 = Decimal128('3.21') 
...  d3 = Decimal128(d1.to_decimal() + d2.to_decimal()) 
... 
>>> print(d3, type(d3)) 
4.44 <class 'bson.decimal128.Decimal128'> 
>>> print(d3.to_decimal(), type(d3.to_decimal())) 
4.44 <class 'decimal.Decimal'> 
>>> decimal.Decimal(d3) 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
TypeError: conversion from Decimal128 to Decimal is not supported 

Und wie Sie oben von den letzten zwei Befehle sehen können, zu Pythons Dezimal-Typ zu werfen, verwenden Sie die Decimal128.to_decimal Methode. Versuchen Sie nicht, eine Dezimal128-Instanz im Dezimalkonstruktor zu übergeben.

Getestet auf Python 3.6 und Pymongo 3.4.

Inspiriert von Pymongos documentation des bson.decimal128 Moduls.

+1

Super danke mein Mann! Mir ist klar, dass die Kopfschmerzen bei der Verwendung dieser "Präzisions" -Wrapper nicht wirklich den vernachlässigbaren Gewinn an Präzision/Genauigkeit wert sind, haha –

Verwandte Themen