2012-02-25 47 views
61

任何人都有使用MongoKit,MongoEngine或Flask-MongoAlchemy for Flask的經驗嗎?MongoKit與MongoEngine和Flask-MongoAlchemy for Flask

你更喜歡哪一個?積極或消極的經歷? Flask-Newbie的選項過多。

+37

似乎有點苛刻關閉此用戶的問題!我發現它很有幫助。 – RubyGladiator 2012-06-27 05:56:57

+1

同上,我發現它也有幫助。 – Tim 2012-10-22 20:18:23

+0

優秀的答案,我發現它很有幫助,我敢打賭別人有好主意 - 重新打開? – 2015-10-23 10:48:23

回答

77

我花了很多時間評估MongoDB的流行Python ORM。這是一個詳盡的練習,因爲我真的想選一個。

我的結論是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。 Mongo上不需要ORM。直接使用Pymongo會給你完全的自由。 – sojin 2012-02-26 07:29:43

+0

優秀的答案! – RubyGladiator 2012-06-27 05:59:37

+0

我喜歡這個答案,但只是想指出,它在大多數情況下並不像僅僅直接返回mongo集合那麼簡單,僅僅是因爲mongo中的最佳做法是縮短字段名稱......尤其是像用戶集合中的某些東西(如果網站是高流量)或分析數據等。基本上,我的問題是,如果在您的休息應用程序中縮短字段名稱,您將如何進行轉換? (即,u - >用戶名,e - >電子郵件等,以節省磁盤和內存消耗) – Jordan 2012-12-05 06:39:06