0
votes

Pymongo: Impossible d'encoder un objet de type décimal.Decimal?

Après avoir essayé de insertion_one dans une collection. Je reçois cette erreur: xxx pré>

Le code fonctionne bien lorsque le JSON n'inclut pas l'objet décimal.decimal code>. S'il y a une solution, vous pouvez également envisager de le coder de manière récursive de rendre l'ensemble du dictionnaire Python JSON_DIC CODE> compatible à être inséré dans MongoDB (car il y a plusieurs instances de la classe décimale. Décimal dans les entrées json.dic code>). p>

Toute aide serait appréciée! p>

EDIT 1: strong> Voici le JSON Je suis avec P>

def iterdict(dict_items, debug_out):
    for k, v in dict_items.items():
        if isinstance(v):
            iterdict(v)
        else:
            dict_items[k] = convert_decimal(v)
    return dict_items


3 commentaires

Veuillez mettre à jour votre message avec le code que vous avez essayé.


J'ai ajouté le code maintenant


Votre code ajouté fonctionne sans erreur sur Mongo version 4.2. Quelle version utilisez-vous? Avez-vous exécuté ce code exact (ne voyez pas de lignes de connexion)?


4 Réponses :


1
votes

pymisto ne reconnaît pas décimal code> - c'est pourquoi vous obtenez l'erreur.

La bonne insertion PYMONGO est col.insert_one ({"Number1": décimal128 ("8.916 ' )}) code>. p>

Vous aurez également besoin de l'importation - de BSON Importation décimal128 code> p>

maintenant, si vous souhaitez traiter votre JSON Fichier sans changer décimal code> à décimal128`, vous pouvez modifier l'instruction d'importation. P>

from bson import Decimal128 as Decimal

coll.insert_one({"number1": Decimal('8.916')})


1 commentaires

Merci Dave, je voudrais dynamiclay insérer des données JSON, mais je travaille avec une chaîne JSON existante. Existe-t-il une façon d'appliquer votre réponse à une chaîne existante récursivement? J'ai maintenant mis à jour la question originale avec mon schéma JSON réel. Merci beaucoup!



2
votes

EDIT:

Le Convert_Decimal () CODE> La fonction effectuera la conversion de décimale en décimal128 dans une structure dict complexe: p> xxx pré>

donne : P>

{'_id': ObjectId('5ea6ec9b52619c7b39b851cb'), 'Number': Decimal128('234.56')}


4 commentaires

Merci Belly, j'ai donné la chaîne de Json et je ne l'appelle pas à partir, est-ce que je peux appliquer votre réponse à une chaîne existante? J'ai mis à jour la question originale avec mon schéma JSON actuel. Merci beaucoup!


Merci pour cette fonction qui fonctionne parfaitement. Dans ma bêtise, je pensais pouvoir fournir une image plus petite de ce que le JSON réel est (que votre code fonctionne parfaitement) mais que Kinldy a-t-il un coup d'oeil au plus grand Json j'ai mis à jour la question avec. Pour une raison quelconque tout en itérant de manière récursive dans ce JSON, votre fonction jette ceci: AttributeError: "décimal.decimal" objet n'a aucun attribut 'éléments' souhaiteriez-vous voir comment votre fonction pourrait être mise à jour vers faire la même chose sur cette chaîne JSON plus longue? Merci beaucoup encore !!


Recherchez une fonction qui recueille une structure dict imbriquée et utilisera une combinaison de cette réponse et de ma réponse. Sera une bonne expérience d'apprentissage!


Merci @belly Buster



0
votes
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')} ]
NOTES:
PyMongo's decimal128 - Support for BSON Decimal128
Python's decimal
module
provides support for decimal floating point arithmetic.
From the PyMongo's decimal128 documentation: 
  To ensure the result of a calculation can always be stored as BSON
  Decimal128 use the context returned by create_decimal128_context() (NOTE: as shown in the example code above).

1 commentaires

Merci prasad_, ce code fonctionne bien si j'avais configuré la variable JSON, mais je l'ai donné dans un fichier, j'ai donc besoin de modifier ivratativement les valeurs après l'importation. La réponse de Belly Buster, donne une fonction qui le fait, mais cela ne fonctionne pas sur mon JSON plus complexe plus complexe. J'ai mis à jour la question à inclure que JSON plus long. Existe-t-il une fonction qui pourrait mettre à jour itérablement les valeurs d'une chaîne JSON qui ne sont pas compatibles avec MongoDB?



0
votes

Je recommanderais simplement d'ajouter un codec pour convertir automatiquement les types de données à l'insertion. Si vous modifiez récursivement les types de données pour utiliser l'objet décimal128, vous risquez de casser la compatibilité avec le code existant.

Vous pouvez suivre le didacticiel pour créer un codec décimal.decimal simple dans les docs PymonGo ici


0 commentaires