Flask-PyMongo - объект типа InsertOneResult не сериализуем в формате JSON - PullRequest
0 голосов
/ 29 сентября 2018

У меня есть API, и я пытаюсь сохранить / опубликовать объект пользователя с помощью Flask-Pymongo.

, но я получаю следующую ошибку

File "/ home /kay / .local / share / virtualenvs / server-iT4jZt3h / lib / python3.7 / site-packages / flask / json / i│ nit .py ", строка 321, в jsonify
│ dumps(данные, отступ = отступ, разделители = разделители) + '\ n', │ File "/home/kay/.local/share/virtualenvs/server-iT4jZt3h/lib/python3.7/site-packages/flask/json/ i│ nit .py ", строка 179, в дампах
│ rv = _json.dumps (obj, ** kwargs) │ Файл" /usr/lib/python3.7/json/ init .py ", строка 238, в дампах
│ ** кВт) .encode (obj) │ Файл" /usr/lib/python3.7/json/encoder.py ", строка 201, вкодировать
│ chunks = list (chunks) │ Файл "/usr/lib/python3.7/json/encoder.py", строка 438, в _iterencode │ o = _default (o) │ File "/ home / kay /link / server / src / run.py ", строка 18, по умолчанию
│ вернуть json.JSONEncoder.default (self, o) │ Файл" /usr/lib/python3.7/json/encoder.py ", строка 179, по умолчанию
│ повышать TypeError (f'Объект типа {o. class . name } ​​'│ TypeError: Объект типа InsertOneResult не является сериализуемым JSON

app / users / resource.py

from flask_restful import Resource
from flask import jsonify, request
from .repository import UsersRepository
from db import mongo


class UsersResource(Resource):

    def __init__(self):

        self.repository = UsersRepository()

    def get(self):

        data = {"Users": "Resource"}
        res = data, 200
        return res

    def post(self):

        req = request.get_json()

        user = {
            "email": req.get("email"),
            "password": req.get("password")
        }

        result = mongo.db.users.insert_one(user)

        return jsonify(result)

run.py

from flask import Flask
from app import api_bp
from db import mongo
from bson.objectid import ObjectId
import json
import datetime
import os

class JSONEncoder(json.JSONEncoder):

    def default(self, o):
        if isinstance(o, ObjectId):
            return str(o)
        if isinstance(o, set):
            return list(o)
        if isinstance(o, datetime.datetime):
            return str(o)
        return json.JSONEncoder.default(self, o)



def create_app(config_filename):

    app = Flask(__name__)
    app.config.from_object(config_filename)
    app.register_blueprint(api_bp, url_prefix='/api')

    mongo.init_app(app)

    app.json_encoder = JSONEncoder

    return app


# def logger():


# def database():


if __name__ == "__main__":
    app = create_app("config")
    app.run(host='0.0.0.0', port=8080, debug=True)

Ответы [ 6 ]

0 голосов
/ 05 июля 2019

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

Решение предполагает, что установлены пакеты pymongo и flask:

from flask import Flask
from flask.json import JSONEncoder

from bson import json_util

from . import resources

# define a custom encoder point to the json_util provided by pymongo (or its dependency bson)
class CustomJSONEncoder(JSONEncoder):
    def default(self, obj): return json_util.default(obj)

application = Flask(__name__)
application.json_encoder = CustomJSONEncoder

if __name__ == "__main__":
    application.run()

0 голосов
/ 04 декабря 2018
from flask_pymongo import Pymongo
import json
import pandas as pd

user = pd.DataFrame(user)

mongo.db.users.insert_one({'email':json.loads(user[0].to_json(orient='index')),                            
                       'password':json.loads(user[1].to_json(orient='index'))})

Это вызовет ошибки, если ваши объекты уже json.Если это не так, он превратит их в json и загрузит их всех за один раз.

0 голосов
/ 04 декабря 2018

Строка TypeError: Object of type InsertOneResult is not JSON serializable описывает проблему.insert_one() возвращает InsertOneResult объект , который содержит вставленный идентификатор (как предложено в комментарии @ styvane), а также флаг, указывающий, была ли запись подтверждена базой данных.Другие операции имеют схожие объекты результата, и ни одна из них не поддерживает сериализацию в формате JSON.

В будущей версии Flask-PyMongo могут быть добавлены вспомогательные средства для поддержки этого, вы можете следовать https://github.com/dcrosta/flask-pymongo/issues/62, чтобы добавлять идеи и предложения.

0 голосов
/ 25 ноября 2018

Простое решение, которое я нашел отсюда:

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

Ответ -> дампы bson (поисковая система) -> jsonзагрузка (десериализация)

Код выглядит следующим образом:

from bson.json_util import dumps,RELAXED_JSON_OPTIONS
import json


def post(self,name):
        dream = {'name':name , 'price' : 12.00 }
        dreams.append(dream)
        dreamDao.addDream(dream) #MongoDB Call to Insert Data 
        bs = dumps(dream,json_options=RELAXED_JSON_OPTIONS) #Now dream has Response Which will have ObjectId
        return json.loads(bs) , 201
0 голосов
/ 29 сентября 2018
  1. из bson.objectid import ObjectId
  2. из bson import json_util

    • использовать pymongo json_util bson для обработки типов BSON
  3. использовать force = true при получении ввода json:

    • req = request.get_json (force = true)
  4. использовать значения по умолчанию при получении полей dict, например:
    • req.get ("email", "")

вы можете проверить, если поляпустой или нет перед вставкой в ​​монго.

0 голосов
/ 29 сентября 2018

Кажется, что то, что вы публикуете на сервере, не является допустимым объектом json.Таким образом, вы должны отладить то, что вы получили.

class UsersResource(Resource):

    def post(self):
        # debug
        print("request.args is {}".format(request.args))
        print("request.form is {}".format(request.form))
        print("request.data is {}".format(request.data))

        req = request.get_json()

        user = {
            "email": req.get("email"),
            "password": req.get("password")
        }

        result = mongo.db.users.insert_one(user)

        return jsonify(result)
...