Zapytanie Flask SQLAlchemy, określ nazwy kolumn

126

Jak określić kolumnę, którą chcę w zapytaniu za pomocą modelu (domyślnie wybiera wszystkie kolumny)? Wiem, jak to zrobić z sesją sqlalchmey: session.query(self.col1)ale jak to zrobić z modelami? Nie mogę SomeModel.query(). Czy jest jakiś sposób?

Matthew Scragg
źródło

Odpowiedzi:

221

Możesz użyć tej with_entities()metody, aby ograniczyć kolumny, które chcesz zwrócić w wyniku. ( dokumentacja )

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

W zależności od wymagań, przydatne mogą być również odroczone płatności. Pozwalają zwrócić cały obiekt, ale ograniczają kolumny przechodzące przez drut.

David McKeone
źródło
21
with_entities () sprawia, że ​​all () daje krotki wartości kolumn, a nie obiektów!
kolypto
10
kolypto: Daje wszystko, o co go poprosisz. SomeModel.query.with_entities (SomeModel) zwróci obiekt. Podobnie jak session.query (SomeModel.col1, SomeModel.col2) zwróci krotki wartości kolumn. Odroczone są tym, czego użyjesz, jeśli nie chcesz, aby kolumny przechodziły przez drut, ale i tak chcesz mieć cały obiekt.
David McKeone,
2
Dzięki, to działa. Ale jak możemy przypisać alias do pola? Ponieważ w moim przypadku używam JOIN i IDpola konfliktu, które jest obecne w obu tabelach
Mitul Shah
Tak, mam to samo pytanie z @MitulShah, jak ustawić alias?
Nam G VU
W przypadku aliasu zobacz tę krótką odpowiedź poniżej, tj. użyj .label() stackoverflow.com/a/11535992/248616
Nam G VU
69
session.query().with_entities(SomeModel.col1)

jest taki sam jak

session.query(SomeModel.col1)

dla aliasu możemy użyć .label ()

session.query(SomeModel.col1.label('some alias name'))
Salil
źródło
2
Drugi zarówno brzmi bardziej logicznie, jak i jest krótszy - wygrana / wygrana
fgblomqvist
7
Twoje pierwsze stwierdzenie jest błędne. Potrzebujesz nawiasów. Powinien więc brzmieć:session.query().with_entities(SomeModel.col1)
JGFMK,
Pierwsza (i trzecia) opcja jest zdecydowanie najlepsza, jeśli chcesz ponownie wykorzystać istniejące obiekty zapytań, szczególnie w przypadku wykonywania wielu złożonych podzapytań.
Jamie Strauss
36

Możesz użyć funkcji load_only :

from sqlalchemy.orm import load_only

fields = ['name', 'addr', 'phone', 'url']
companies = session.query(SomeModel).options(load_only(*fields)).all()
Vlad Bezden
źródło
1
To rozwiązanie jest najlepsze, ponieważ nadal działa jako obiekt, a nie tylko lista wyników.
rborodinov
Brawa dla Ciebie za to rozwiązanie. Ma wiele zalet: - zwraca dokładnie ten sam typ obiektu, co .first()i .one()(co spowoduje leniwe / niecierpliwe ładowanie pól i relacji), - można ustawić jako komponent zapytania
Damien
kod jest czysty, ale kwerenda sql wybiera wszystkie pola z bazy danych. Użyłem with_entitiesjak podano w zaakceptowanej odpowiedzi, a zapytanie wybrało tylko te pola /.
Srikanth Jeeva
11

Możesz użyć Model.query, ponieważ Model(lub zwykle jego klasa bazowa, szczególnie w przypadkach, gdy używane jest deklaratywne rozszerzenie) jest przypisana Sesssion.query_property. W tym przypadku Model.queryjest odpowiednikiem Session.query(Model).

Nie znam sposobu modyfikowania kolumn zwracanych przez zapytanie (z wyjątkiem dodawania kolejnych za pomocą add_columns()).
Więc najlepszym strzałem jest użycie Session.query(Model.col1, Model.col2, ...)(jak już pokazał Salil).

awangarda
źródło
Wydaje mi się, że może istnieć również sposób na zrobienie tego z listą kolumn dla wartości zapytań (), docs.sqlalchemy.org/en/latest/orm/ ... - ale cukier składniowy listy umyka mi w tej chwili.
JGFMK,
3

Możesz użyć Query.values, Query.values

session.query(SomeModel).values('id', 'user')

gaozhidf
źródło
-11

Oto przykład:

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

Pytam w bazie danych o filmy z oceną <> 0, a następnie sortuję je według oceny z najwyższą oceną.

Spójrz tutaj: Wybierz, Wstaw, Usuń w Flask-SQLAlchemy

happygoat
źródło