Получение 'TypeError: ObjectId (' ') не является сериализуемым JSON' при использовании Flask 0.10.1

Я разработал пример Flask, Minitwit, для работы с MongoDB, и он отлично работал на Flask 0.9, но после обновления до 0.10.1 я получаю ошибку в заголовке при входе в систему, когда пытаюсь установить идентификатор сеанса.

Кажется, в Flask 0.10.1 произошли изменения, связанные с json.

Фрагмент кода:

user = db.minitwit.user.find_one({'username': request.form['username']}) session['_id'] = user['_id'] 

Полный код в моем реестре github .

В принципе, я устанавливаю идентификатор сеанса Flask для _id пользователя из MongoDB.

Я пробовал первые два решения из этого вопроса SO без успеха.

Ну, занятие session ['_ id'] = str (user ['_ id']) избавляется от сообщения об ошибке, и я правильно перенаправлен на страницу временной шкалы, но я фактически не вошел в систему.

Как я могу это исправить?

EDIT: копирование / вставка трассировки: http://pastebin.com/qa0AL1fk

Спасибо.

4 Solutions collect form web for “Получение 'TypeError: ObjectId (' ') не является сериализуемым JSON' при использовании Flask 0.10.1”

EDIT: Еще проще исправить. Вам даже не нужно кодировать / декодировать JSON.

Просто сохраните сеанс ['_ id'] в виде строки:

 user = db.minitwit.user.find_one({'username': request.form['username']}) session['_id'] = str(user['_id']) 

И тогда везде, где вы хотите что-то сделать с сеансом ['_ id'], вы должны обернуть его ObjectId (), чтобы он передавался как объект ObjectId в MongoDB.

 if '_id' in session: g.user = db.minitwit.user.find_one({'_id': session['_id']}) 

чтобы:

 if '_id' in session: g.user = db.minitwit.user.find_one({'_id': ObjectId(session['_id'])}) 

Вы можете увидеть полный diff для исправления в моем реестре github .

Если кто-то заботится о том, почему «TypeError: ObjectId ('') не является сериализуемым JSON« проблемой », появившимся в Flask 0.10.1, это связано с тем, что они изменили способ хранения сеансов. Теперь они хранятся как JSON, так как объект «_id» в MongoDB не является стандартным JSON, он не смог сериализовать токен сеанса, тем самым предоставив TypeError. Читайте об изменениях здесь: http://flask.pocoo.org/docs/upgrading/#upgrading-to-010

JSON поддерживает сериализацию (кодирование / декодирование) ограниченного набора типов объектов по умолчанию. Вы могли бы расширить декодер / кодировщик JSON Python, чтобы справиться с этой ситуацией.

Что касается кодирования объекта, который содержится в ObjectID, например, когда ObjectIds создаются на стороне клиента, которые будут переданы на некоторый ожидающий сервер, попробуйте:

 import json from bson.objectid import ObjectId class Encoder(json.JSONEncoder): def default(self, obj): if isinstance(obj, ObjectId): return str(obj) else: return obj 

Затем в своем коде перед тем, как нажать клиентский клиент данных -> server, запустите:

 json.dumps(obj, cls=Encoder) 

На стороне сервера, если мы знаем, что имеем дело с документами mongo (объект словаря с ключом «_id»), мы можем определить крючок json-декодера следующим образом:

 def decoder(dct): for k, v in dct.items(): if '_id' in dct: try: dct['_id'] = ObjectId(dct['_id']) except: pass return dct 

И назовите его, используя следующий вызов:

 doc = json.loads(in_doc, object_hook=decoder) 

Вам, вероятно, придется немного адаптировать этот код, но для простого случая прохождения

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

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

toString преобразует его в строку и может сохранять в сеансе:

 session['_id'] = user['_id'].toString() 

альтернативный session['_id'] = str(user['_id'])

Приведенное выше исправило ошибку для меня.

  • Самоподписанное SSL-соединение с использованием PyMongo
  • Веб-сайты Windows Azure python
  • Вопрос о safe = Истинный параметр для операции обновления mongodb
  • Mongoengine PointField дает ожидаемый объект местоположения, массив местоположений не соответствует правильной ошибке формата
  • Как читать коллекцию в кусках на 1000?
  • отказ импортировать pymongo ubuntu
  • MongoDB: как получить db.stats () из API
  • Сокращение числа карт не удалось с помощью pymongo, но успех в оболочке mongo
  • Python - лучший язык программирования в мире.