MongoKit与MongoEngine与Flask-MongoAlchemy for Flask [关闭]


75

任何人都有使用MongoKit,MongoEngine或Flask-MongoAlchemy for Flask的经验吗?

你更倾向哪个?积极或消极的经历?Flask-Newbie的选择太多。


44
似乎很难解决这个用户问题!我发现它很有帮助。
RubyGladiator 2012年

1
同上,我发现它也有帮助。
蒂姆(Tim)

很好的答案,我发现这很有帮助,我敢打赌其他人有好主意-重新开放?
jowan sebastian 2015年

谁可以重新提出这个问题?,取决于我吗?
oscarmlage,2015年

好问题!
Anekdotin

Answers:


87

我花了很多时间评估MongoDB的流行Python ORM。这是一项详尽的练习,因为我真的很想选一个。

我的结论是,ORM消除了MongoDB带来的乐趣。没有人感到自然,他们施加的限制类似于使我首先脱离关系数据库的限制。

再说一次,我真的很想使用ORM,但是现在我确信pymongo直接使用是可行的方法。现在,我遵循一个包含MongoDB,pymongoPython和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标题。

当然,您需要清理您的输入,并且所提供的代码将无法正常工作(我的意思是作为示例,但这并不难理解我的观点)。

我再次尝试了所有方法,但是这种体系结构使我的代码变得灵活,简单和可扩展。


11
+1。您不需要在Mongo上使用ORM。直接使用Pymongo将给您完全的自由。
sojin 2012年

我喜欢这个答案,但要注意的是,在大多数情况下,它并不像直接返回mongo集合那样简单,只是因为mongo的最佳做法是缩短字段名称...尤其是诸如用户集合(如果网站上的流量很高)或分析数据等。基本上,我的问题是,如果在其余应用程序中将字段名称缩短,该如何转换字段名称?(即,u->用户名,e->电子邮件等,以节省磁盘和内存消耗)
约旦

1
@Arrieta您如何看待烧瓶pymongo?似乎可以将其与flask-classy一起使用以实现相同的效果。
Chris2048 2013年

@ Chris2048我是Flask-Classy的创建者,正是出于这个目的,我们在工作的主应用程序中将两者混合在一起。
apiguy 2013年

3
@tim我不知道三年前写这本书时在想什么,但是现在我的建议是您使用工具,因为您知道它可以解决您要解决的问题。在大多数情况下,可靠的关系数据库(如Postgres)将解决您所有的数据持久性,聚合和分析问题,同时以软件尚未实现的增长方式保护您的数据。
Conrad.Dean
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.