Hat jemand Erfahrungen mit MongoKit, MongoEngine oder Flask-MongoAlchemy for Flask?
Welches bevorzugen Sie? Positive oder negative Erfahrungen?. Zu viele Optionen für einen Flask-Newbie.
Hat jemand Erfahrungen mit MongoKit, MongoEngine oder Flask-MongoAlchemy for Flask?
Welches bevorzugen Sie? Positive oder negative Erfahrungen?. Zu viele Optionen für einen Flask-Newbie.
Antworten:
Ich habe viel Zeit investiert, um die beliebten Python-ORMs für MongoDB zu evaluieren. Dies war eine erschöpfende Übung, da ich wirklich eine auswählen wollte.
Mein Fazit ist, dass ein ORM den Spaß aus MongoDB entfernt. Keiner fühlt sich natürlich an, sie legen ähnliche Einschränkungen fest wie diejenigen, die mich dazu gebracht haben, mich von relationalen Datenbanken zu entfernen.
Auch hier wollte ich unbedingt ein ORM verwenden, aber jetzt bin ich davon überzeugt, dass die pymongodirekte Verwendung der richtige Weg ist. Jetzt folge ich einem Muster, das MongoDB pymongound Python umfasst.
Eine ressourcenorientierte Architektur führt zu sehr natürlichen Darstellungen. Nehmen Sie zum Beispiel die folgende Benutzerressource:
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)
Die ResourceBasisklasse sieht aus wie
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)
Beachten Sie, dass ich die WSGISpezifikation direkt verwende und Werkzeugwenn möglich nutze (übrigens denke ich, dass dies Flaskeine unnötige Komplikation darstellt Werkzeug).
Die Funktion verwendet representationdie AcceptHeader der Anforderung und erstellt eine geeignete Darstellung (z. B. application/jsonoder text/html). Es ist nicht schwer zu implementieren. Außerdem wird der Last-ModifiedHeader hinzugefügt.
Natürlich muss Ihre Eingabe bereinigt werden, und der dargestellte Code funktioniert nicht (ich meine es als Beispiel, aber es ist nicht schwer, meinen Standpunkt zu verstehen).
Wieder habe ich alles versucht, aber diese Architektur hat meinen Code flexibel, einfach und erweiterbar gemacht.