Flask SQLAlchemy-Abfrage, Spaltennamen angeben

125

Wie gebe ich die gewünschte Spalte in meiner Abfrage mithilfe eines Modells an (standardmäßig werden alle Spalten ausgewählt)? Ich weiß, wie man das mit der sqlalchmey-Sitzung macht:, session.query(self.col1)aber wie mache ich das mit Modellen? Ich kann es nicht tun SomeModel.query(). Gibt es einen Weg?

Matthew Scragg
quelle

Antworten:

220

Mit dieser with_entities()Methode können Sie einschränken, welche Spalten im Ergebnis zurückgegeben werden sollen. ( Dokumentation )

result = SomeModel.query.with_entities(SomeModel.col1, SomeModel.col2)

Abhängig von Ihren Anforderungen können Sie auch aufgeschobene Informationen als nützlich erachten . Mit ihnen können Sie das vollständige Objekt zurückgeben, aber die Spalten, die über den Draht kommen, einschränken.

David McKeone
quelle
21
with_entities () lässt all () Tupel von Spaltenwerten liefern, keine Objekte!
kolypto
10
kolypto: Es gibt alles, was Sie von ihm verlangen. SomeModel.query.with_entities (SomeModel) würde das Objekt ergeben. Genau wie session.query (SomeModel.col1, SomeModel.col2) würde Tupel von Spaltenwerten ergeben. Zurückgestellte sind das, was Sie verwenden würden, wenn Sie nicht möchten, dass Spalten über den Draht kommen, aber Sie möchten trotzdem das gesamte Objekt.
David McKeone
2
Danke, es funktioniert. Aber wie können wir dem Feld einen Alias ​​zuweisen? Weil ich in meinem Fall JOIN und das Konfliktfeld verwende ID, das in beiden Tabellen vorhanden ist
Mitul Shah
Ja, ich habe die gleiche Frage mit @MitulShah, wie man einen Alias ​​setzt.
Nam G VU
Sehen Sie sich als Alias ​​diese kurze Antwort unten an, d. H. Verwenden Sie .label() stackoverflow.com/a/11535992/248616
Nam G VU
69
session.query().with_entities(SomeModel.col1)

ist das gleiche wie

session.query(SomeModel.col1)

Für den Alias ​​können wir .label () verwenden.

session.query(SomeModel.col1.label('some alias name'))
Salil
quelle
2
Der zweite klingt beide logischer und ist kürzer - win / win
fgblomqvist
7
Ihre erste Aussage ist falsch. Sie benötigen Klammern. Also sollte es lauten:session.query().with_entities(SomeModel.col1)
JGFMK
Die erste (und dritte) Option ist bei weitem die beste, wenn Sie vorhandene Abfrageobjekte wiederverwenden möchten, insbesondere bei der Ausführung mehrerer komplexer Unterabfragen.
Jamie Strauss
36

Sie können die Funktion load_only verwenden:

from sqlalchemy.orm import load_only

fields = ['name', 'addr', 'phone', 'url']
companies = session.query(SomeModel).options(load_only(*fields)).all()
Vlad Bezden
quelle
1
Diese Lösung ist die beste, da sie immer noch als Objekt funktioniert, nicht nur als Ergebnisliste.
Rborodinov
Ein großes Lob an Sie für diese Lösung. Es hat viele Vorteile: - genau den gleichen Objekttyp zurückgeben wie .first()und .one()(der Felder und Beziehungen faul / eifrig lädt), - kann als Abfragekomponente festgelegt werden
Damien
Der Code ist sauber, aber die SQL-Abfrage wählt alle Felder aus der Datenbank aus. Ich habe with_entitieswie in der akzeptierten Antwort angegeben verwendet und die Abfrage nur diese Felder / ausgewählt.
Srikanth Jeeva
11

Sie können verwenden Model.query, weil die Model(oder normalerweise ihre Basisklasse, insbesondere in Fällen, in denen eine deklarative Erweiterung verwendet wird) zugewiesen ist Sesssion.query_property. In diesem Fall Model.queryentspricht das Session.query(Model).

Mir ist nicht bekannt, wie die von der Abfrage zurückgegebenen Spalten geändert werden können (außer durch Hinzufügen weiterer Spalten add_columns()).
Ihr bester Schuss ist also, das zu verwenden Session.query(Model.col1, Model.col2, ...)(wie bereits von Salil gezeigt).

van
quelle
Ich glaube, es gibt auch eine Möglichkeit, dies mit einer Liste von Spalten für Abfragewerte () zu tun , docs.sqlalchemy.org/en/latest/orm/… - aber der syntaktische Zucker für die Liste entgeht mir im Moment.
JGFMK
-11

Ein Beispiel hier:

movies = Movie.query.filter(Movie.rating != 0).order_by(desc(Movie.rating)).all()

Ich frage die Datenbank nach Filmen mit der Bewertung <> 0 ab und bestelle sie dann, indem ich sie zuerst mit der höchsten Bewertung bewerte.

Schauen Sie hier: Wählen, Einfügen, Löschen in Flask-SQLAlchemy

Happygoat
quelle