Comment corriger Python MongoDB TypeError : Object of type ObjectId is not JSON serializable
Problème :
En essayant d’exporter des données en JSON qui ont été initialement interrogées depuis MongoDB en utilisant du code comme
mongo_json_fix.py
with open("alle.json", "w") as outfile:
json.dump(alle, outfile)vous voyez le message d’erreur suivant :
mongodb_objectid_json_error.txt
File /usr/lib/python3.9/json/__init__.py:179, in dump(obj, fp, skipkeys, ensure_ascii, check_circular, allow_nan, cls, indent, separators, default, sort_keys, **kw)
173 iterable = cls(skipkeys=skipkeys, ensure_ascii=ensure_ascii,
174 check_circular=check_circular, allow_nan=allow_nan, indent=indent,
175 separators=separators,
176 default=default, sort_keys=sort_keys, **kw).iterencode(obj)
177 # could accelerate with writelines in some versions of Python, at
178 # a debuggability cost
--> 179 for chunk in iterable:
180 fp.write(chunk)
File /usr/lib/python3.9/json/encoder.py:429, in _make_iterencode.<locals>._iterencode(o, _current_indent_level)
427 yield _floatstr(o)
428 elif isinstance(o, (list, tuple)):
--> 429 yield from _iterencode_list(o, _current_indent_level)
430 elif isinstance(o, dict):
431 yield from _iterencode_dict(o, _current_indent_level)
File /usr/lib/python3.9/json/encoder.py:325, in _make_iterencode.<locals>._iterencode_list(lst, _current_indent_level)
323 else:
324 chunks = _iterencode(value, _current_indent_level)
--> 325 yield from chunks
326 if newline_indent is not None:
327 _current_indent_level -= 1
File /usr/lib/python3.9/json/encoder.py:405, in _make_iterencode.<locals>._iterencode_dict(dct, _current_indent_level)
403 else:
404 chunks = _iterencode(value, _current_indent_level)
--> 405 yield from chunks
406 if newline_indent is not None:
407 _current_indent_level -= 1
File /usr/lib/python3.9/json/encoder.py:438, in _make_iterencode.<locals>._iterencode(o, _current_indent_level)
436 raise ValueError("Circular reference detected")
437 markers[markerid] = o
--> 438 o = _default(o)
439 yield from _iterencode(o, _current_indent_level)
440 if markers is not None:
File /usr/lib/python3.9/json/encoder.py:179, in JSONEncoder.default(self, o)
160 def default(self, o):
161 """Implement this method in a subclass such that it returns
162 a serializable object for ``o``, or calls the base implementation
163 (to raise a ``TypeError``).
(...)
177
178 """
--> 179 raise TypeError(f'Object of type {o.__class__.__name__} '
180 f'is not JSON serializable')
TypeError: Object of type ObjectId is not JSON serializableSolution
Cette erreur se produit parce que les objets interrogés depuis PyMongo contiennent toujours _id qui est de type ObjectId et la bibliothèque JSON normale (ou les remplacements drop-in comme simplejson ne savent pas comment créer des représentations JSON des Objects de type ObjectId).
Afin de corriger cela, utilisez json_util de pymongo au lieu de json. Notez que le paquet bson.json_util contient dumps mais ne contient pas dump, donc utilisez le snippet suivant pour écrire dans un fichier :
mongo_json_util_fix.py
import bson.json_util as json_util
with open("alle.json", "w") as outfile:
outfile.write(json_util.dumps(alle))Si cet article vous a aidé, pensez à m'offrir un café ou à faire un don via PayPal pour soutenir la recherche et la publication de nouveaux articles sur TechOverflow