TypeError: ObjectId ('') не является сериализуемым JSON

Мой ответ вернулся из MongoDB после запроса агрегированной функции в документе с использованием Python, он возвращает действительный ответ, и я могу его распечатать, но не могу его вернуть.

Ошибка:

TypeError: ObjectId('51948e86c25f4b1d1c0d303c') is not JSON serializable 

Распечатать:

 {'result': [{'_id': ObjectId('51948e86c25f4b1d1c0d303c'), 'api_calls_with_key': 4, 'api_calls_per_day': 0.375, 'api_calls_total': 6, 'api_calls_without_key': 2}], 'ok': 1.0} 

Но когда я пытаюсь вернуться:

 TypeError: ObjectId('51948e86c25f4b1d1c0d303c') is not JSON serializable 

Это вызов RESTfull:

 @appv1.route('/v1/analytics') def get_api_analytics(): # get handle to collections in MongoDB statistics = sldb.statistics objectid = ObjectId("51948e86c25f4b1d1c0d303c") analytics = statistics.aggregate([ {'$match': {'owner': objectid}}, {'$project': {'owner': "$owner", 'api_calls_with_key': {'$cond': [{'$eq': ["$apikey", None]}, 0, 1]}, 'api_calls_without_key': {'$cond': [{'$ne': ["$apikey", None]}, 0, 1]} }}, {'$group': {'_id': "$owner", 'api_calls_with_key': {'$sum': "$api_calls_with_key"}, 'api_calls_without_key': {'$sum': "$api_calls_without_key"} }}, {'$project': {'api_calls_with_key': "$api_calls_with_key", 'api_calls_without_key': "$api_calls_without_key", 'api_calls_total': {'$add': ["$api_calls_with_key", "$api_calls_without_key"]}, 'api_calls_per_day': {'$divide': [{'$add': ["$api_calls_with_key", "$api_calls_without_key"]}, {'$dayOfMonth': datetime.now()}]}, }} ]) print(analytics) return analytics 

db хорошо связан, и коллекция тоже есть, и я вернул действительный ожидаемый результат, но когда я пытаюсь вернуться, он дает мне ошибку Json. Любая идея, как преобразовать ответ обратно в JOSON. благодаря

  • Многопроцессорность Python: как я могу делиться между несколькими процессами?
  • Разбить массив NumPy в соответствии со значениями в массиве (условие)
  • PyQt QTcpServer: как вернуть данные нескольким клиентам?
  • Что такое метод работы .join () для процесса многопроцессорности Python?
  • Перенаправление электронной почты с помощью python smtplib
  • Почему не работает isnumeric?
  • Быстрая замена значений в массиве numpy
  • Атрибуты объекта Python - методология доступа
  • 8 Solutions collect form web for “TypeError: ObjectId ('') не является сериализуемым JSON”

    Вы должны определить свой собственный JSONEncoder и использовать его:

     import json from bson import ObjectId class JSONEncoder(json.JSONEncoder): def default(self, o): if isinstance(o, ObjectId): return str(o) return json.JSONEncoder.default(self, o) JSONEncoder().encode(analytics) 

    Его также можно использовать следующим образом.

     json.encode(analytics, cls=JSONEncoder) 

    Pymongo предоставляет json_util – вы можете использовать его вместо этого для обработки типов BSON

     >>> from bson import Binary, Code >>> from bson.json_util import dumps >>> dumps([{'foo': [1, 2]}, ... {'bar': {'hello': 'world'}}, ... {'code': Code("function x() { return 1; }")}, ... {'bin': Binary("")}]) '[{"foo": [1, 2]}, {"bar": {"hello": "world"}}, {"code": {"$code": "function x() { return 1; }", "$scope": {}}}, {"bin": {"$binary": "AQIDBA==", "$type": "00"}}]' 

    Фактический пример из json_util .

    В отличие от jsonify от Flask, «дампы» возвращают строку, поэтому ее нельзя использовать как замену jsonify Flask в 1: 1.

    Но этот вопрос показывает, что мы можем сериализовать с помощью json_util.dumps (), преобразовать обратно в dict с помощью json.loads () и, наконец, вызвать jsonify Flask на нем.

    Пример (полученный из ответа предыдущего вопроса):

     from bson import json_util, ObjectId import json #Lets create some dummy document to prove it will work page = {'foo': ObjectId(), 'bar': [ObjectId(), ObjectId()]} #Dump loaded BSON to valid JSON string and reload it as dict page_sanitized = json.loads(json_util.dumps(page)) return page_sanitized 

    Это решение преобразует ObjectId и другие (например, Binary, Code и т. Д.) В эквивалент строки, такой как «$ oid».

    Выход JSON будет выглядеть так:

     { "_id": { "$oid": "abc123" } } 

    В качестве быстрой замены вы можете изменить {'owner': objectid} на {'owner': str(objectid)} .

    Но определение вашего собственного JSONEncoder – лучшее решение, это зависит от ваших требований.

     from bson import BSON from bson import json_util import json @app.route('/') def index(): for _ in "collection_name".find(): return json.dumps(i, indent=4, default=json_util.default) 

    Это пример примера для преобразования BSON в объект JSON. Вы можете попробовать это.

    Флажок jsonify обеспечивает повышение безопасности, как описано в JSON Security . Если пользовательский кодер используется с Flask, лучше рассмотреть точки, обсуждаемые в JSON Security

    Вот как я недавно исправил ошибку

      @app.route('/') def home(): docs = [] for doc in db.person.find(): doc.pop('_id') docs.append(doc) return jsonify(docs) 

    Я знаю, что я опаздываю, но думал, что это поможет хотя бы нескольким людям!

    Оба примера, упомянутые tim и defuz (которые проголосовали за верхние), отлично работают. Тем не менее, есть небольшая разница, которая иногда может быть значительной.

    1. Следующий метод добавляет одно дополнительное поле, которое является избыточным и может быть не идеальным во всех случаях

    Pymongo предоставляет json_util – вы можете использовать его вместо этого для обработки типов BSON

    Результат: {"_id": {"$ oid": "abc123"}}

    1. Где, поскольку класс JsonEncoder дает тот же результат в строковом формате, что и нам, и нам нужно также использовать json.loads (output). Но это приводит к

    Выход: {"_id": "abc123"}

    Несмотря на то, что первый метод выглядит просто, оба метода требуют очень минимальных усилий.

    Interesting Posts

    Обнаружение интерпретатора завершено в потоке демона

    NameError для использования timeit в python

    Применение низкоуровневых клавиатурных крючков с Python и SetWindowsHookExA

    Как создать новые строки в кадре данных pandas, содержащем слова в строке существующей строки?

    Python подключается к Hive, используя pyhs2 и аутентификацию Kerberos

    Отправлять сообщения журнала из всех задач сельдерея в один файл

    Хронические устаревшие результаты с использованием MySQLdb в Python

    когда использовать pre_save, save, post_save в django?

    Почему PEP-8 указывает максимальную длину строки в 79 символов?

    Добавление метки оси y к вторичной оси y в matplotlib

    При вызове super () в производном классе я могу передать сам .__ class__?

    Могу ли я создать список из регулярных выражений?

    Pythonic способ проверить, выполняется ли условие для любого элемента списка

    Поведение цикла «За» для Python

    Разница между использованием запятых, конкатенацией и форматированием строк в Python

    Python - лучший язык программирования в мире.