MongoKit vs MongoEngine vs Flask-MongoAlchemy für Flask [geschlossen]

74

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.

Oscarmlage
quelle
44
Scheint ein bisschen hart zu sein, um diese Benutzerfrage zu schließen! Ich fand es hilfreich.
RubyGladiator
1
Das Gleiche fand ich auch hilfreich.
Tim
Ausgezeichnete Antwort, ich fand es hilfreich, ich wette, andere haben gute Ideen - wieder öffnen?
Jowan Sebastian
Wer könnte die Frage wieder öffnen? Kommt es auf mich an?
Oscarmlage
tolle Frage!
Anekdotin

Antworten:

87

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.

Escualo
quelle
11
+1. Sie brauchen kein ORM über Mongo. Wenn Sie Pymongo direkt verwenden, haben Sie völlige Freiheit.
Sojin
Ich mag diese Antwort, möchte aber nur darauf hinweisen, dass es in den meisten Fällen nicht so einfach ist, die Mongo-Sammlung direkt zurückzugeben, nur weil die beste Vorgehensweise in Mongo darin besteht, Feldnamen zu verkürzen ... insbesondere etwas in der Sammlung eines Benutzers (wenn Website ist stark frequentiert) oder analytische Daten usw. Grundsätzlich ist meine Frage, wie würden Sie Feldnamen transformieren, wenn sie in Ihrer Rest-App gekürzt würden? (dh u -> Benutzername, E -> E-Mail usw., um Festplatten- und Speicherverbrauch zu sparen)
Jordanien
1
@Arrieta Was denkst du über Flask-Pymongo? Scheint, als würde es mit Flask-Classy verwendet werden, um fast das Gleiche zu erreichen.
Chris2048
@ Chris2048 Ich bin der Schöpfer von Flask-Classy und wir mischen diese beiden in unserer Hauptanwendung bei der Arbeit genau zu diesem Zweck zusammen.
Apiguy
3
@tim Ich weiß nicht, was ich dachte, als ich das vor drei Jahren schrieb, aber mein Rat im Moment ist, dass Sie Werkzeuge verwenden, weil Sie wissen, dass es das Problem löst, das Sie lösen möchten. In den meisten Fällen löst eine zuverlässige relationale Datenbank wie Postgres alle Probleme mit der Persistenz, Aggregation und Analyse Ihrer Daten und schützt Ihre Daten gleichzeitig auf eine Weise, die Sie im Zuge des weiteren Wachstums Ihrer Software noch nicht erkannt haben.
Conrad.Dean