Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

MongoKit vs MongoEngine vs Flask-MongoAlchemy for Flask [closed]

Anyone has experiences with MongoKit, MongoEngine or Flask-MongoAlchemy for Flask?

Which one do you prefer? Positive or negative experiences?. Too many options for a Flask-Newbie.

like image 944
oscarmlage Avatar asked Feb 25 '12 20:02

oscarmlage


People also ask

Which is better PyMongo or MongoEngine?

Both PyMongo and MongoEngine can be used to access data from a MongoDB database. However, they work in very different ways and offer different features. PyMongo is the MongoDB recommended library. It makes it easy to use MongoDB documents and maps directly to the familiar MongoDB Query Language.

What is the difference between PyMongo and MongoEngine?

While both PyMongo and MongoEngine do both return objects (which is not wrong), PyMongo returns dictionaries that need to have their keys referenced by string. MongoEngine allows you to define a schema via classes for your document data.

What is MongoAlchemy?

MongoAlchemy is another ORM-like layer on top of PyMongo. Its API is inspired by SQLAlchemy. The code is available on github; for more information, see the tutorial. MongoEngine. MongoEngine is another ORM-like layer on top of PyMongo.


1 Answers

I have invested a lot of time evaluating the popular Python ORMs for MongoDB. This was an exhaustive exercise, as I really wanted to pick one.

My conclusion is that an ORM removes the fun out of MongoDB. None feels natural, they impose restrictions similar to the ones which made me move away from relational databases in the first place.

Again, I really wanted to use an ORM, but now I am convinced that using pymongo directly is the way to go. Now, I follow a pattern which embraces MongoDB, pymongo, and Python.

A Resource Oriented Architecture leads to very natural representations. For instance, take the following User resource:

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) 

The Resource base class looks like

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) 

Notice that I use the WSGI spec directly, and leverage Werkzeug where possible (by the way, I think that Flask adds an unnecessary complication to Werkzeug).

The function representation takes the request's Accept headers, and produces a suitable representation (for example, application/json, or text/html). It is not difficult to implement. It also adds the Last-Modified header.

Of course, your input needs to be sanitized, and the code, as presented, will not work (I mean it as an example, but it is not difficult to understand my point).

Again, I tried everything, but this architecture made my code flexible, simple, and extensible.

like image 93
Escualo Avatar answered Sep 23 '22 05:09

Escualo