2012-02-25 3 views
61

У кого-нибудь есть опыт работы с MongoKit, MongoEngine или Flask-MongoAlchemy для Flask?MongoKit vs MongoEngine vs Flask-MongoAlchemy for Flask

Какой вам больше нравится? Положительные или отрицательные переживания ?. Слишком много вариантов для Flask-Newbie.

+37

Кажется немного суровым, чтобы закрыть этот вопрос пользователей! Я нашел это полезным. – RubyGladiator

+1

То же, я тоже нашел его полезным. – Tim

+0

Отличный ответ, я сочла его полезным, держу пари, у других есть хорошие идеи - снова открыть? –

ответ

77

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

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

Опять же, я действительно хотел использовать ORM, но теперь я убежден, что использование pymongo напрямую - это путь. Теперь я следую шаблону, который охватывает MongoDB, pymongo и Python.

Ресурсно-ориентированная архитектура ведет к очень естественным представлениям. Например, возьмем следующий ресурс пользователя:

from werkzeug.wrappers import Response 
from werkzeug.exceptions import NotFound 

Users = pymongo.Connection("localhost", 27017)["mydb"]["users"] 


class User(Resource): 

    def GET(self, request, username): 
     spec = { 
      "_id": username, 
      "_meta.active": True 
     } 
     # this is a simple call to pymongo - really, do 
     # we need anything else? 
     doc = Users.find_one(spec) 
     if not doc: 
      return NotFound(username) 
     payload, mimetype = representation(doc, request.accept) 
     return Response(payload, mimetype=mimetype, status=200) 

    def PUT(self, request, username): 
     spec = { 
      "_id": username, 
      "_meta.active": True 
     } 
     operation = { 
      "$set": request.json, 
     } 
     # this call to pymongo will return the updated document (implies safe=True) 
     doc = Users.update(spec, operation, new=True) 
     if not doc: 
      return NotFound(username) 
     payload, mimetype = representation(doc, request.accept) 
     return Response(payload, mimetype=mimetype, status=200) 

Resource базовый класс выглядит

class Resource(object): 

    def GET(self, request, **kwargs): 
     return NotImplemented() 

    def HEAD(self, request, **kwargs): 
     return NotImplemented() 

    def POST(self, request, **kwargs): 
     return NotImplemented() 

    def DELETE(self, request, **kwargs): 
     return NotImplemented() 

    def PUT(self, request, **kwargs): 
     return NotImplemented() 

    def __call__(self, request, **kwargs): 
     handler = getattr(self, request.method) 
     return handler(request, **kwargs) 

Обратите внимание, что я использую WSGI спецификации непосредственно, и рычаги Werkzeug, где это возможно (кстати, я думаю, что Flask добавляет ненужное осложнение к Werkzeug).

Функция representation принимает Accept заголовкам запроса, и производит соответствующее представление (например, application/json или text/html). Это не сложно реализовать. Он также добавляет заголовок Last-Modified.

Конечно, ваш вход нуждается в дезинфекции, и код, представленный, не будет работать (я имею в виду это как пример, но нетрудно понять мою точку зрения).

Опять же, я пробовал все, но эта архитектура сделала мой код гибким, простым и расширяемым.

+9

+1. Вам не нужно ORM сверху Монго. Использование Pymongo напрямую даст вам полную свободу. – sojin

+0

Отличный ответ! – RubyGladiator

+0

Мне нравится этот ответ, но просто хочу отметить, что это в большинстве случаев не так просто, как просто возвращение коллекции манго непосредственно только потому, что лучшая практика в монго заключается в сокращении имен полей ... особенно что-то вроде коллекции пользователя (если сайт имеет высокий трафик), или аналитические данные и т. д. В основном, мой вопрос: как бы вы изменили имена полей, если они были сокращены в вашем приложении для отдыха? (т. е. u -> имя пользователя, e -> электронная почта и т. д., чтобы сохранить потребление диска и памяти) – Jordan