Запрос Flask SQLAlchemy, укажите имена столбцов

126

Как указать столбец, который мне нужен в моем запросе, используя модель (по умолчанию она выбирает все столбцы)? Я знаю, как это сделать с помощью сеанса sqlalchmey:, session.query(self.col1)но как мне это сделать с моделями? Я не могу SomeModel.query(). Есть способ?

Мэтью Скрэгг
источник

Ответы:

221

Вы можете использовать этот with_entities()метод, чтобы ограничить столбцы, которые вы хотите вернуть в результате. ( документация )

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

В зависимости от ваших требований, вам также могут быть полезны отсрочки . Они позволяют вам возвращать объект полностью, но ограничивают столбцы, которые проходят через провод.

Дэвид МакКеоне
источник
21
with_entities () заставляет all () выдавать кортежи значений столбцов, а не объекты!
kolypto
10
kolypto: Он дает все, что вы его просите. SomeModel.query.with_entities (SomeModel) даст объект. Так же, как session.query (SomeModel.col1, SomeModel.col2) будет выдавать кортежи значений столбцов. Отсрочки - это то, что вы бы использовали, если вы не хотите, чтобы столбцы проходили через провод, но вам все равно нужен весь объект.
Дэвид МакКеон
2
Спасибо, это работает. Но как мы могли присвоить полю псевдоним? Потому что в моем случае я использую JOIN и IDполе конфликта, которое присутствует в обеих таблицах
Митул Шах
Да, у меня такой же вопрос с @MitulShah, как установить псевдоним?
Nam G VU
Для псевдонима просмотрите этот краткий ответ ниже, т.е. используйте .label() stackoverflow.com/a/11535992/248616
Nam G VU
69
session.query().with_entities(SomeModel.col1)

такой же как

session.query(SomeModel.col1)

для псевдонима мы можем использовать .label ()

session.query(SomeModel.col1.label('some alias name'))
Salil
источник
2
Второй
вариант
7
Ваше первое утверждение неверно. Вам нужны скобки. Итак, он должен читать:session.query().with_entities(SomeModel.col1)
JGFMK
Первый (и третий) варианты, безусловно, являются лучшими, если вы хотите повторно использовать существующие объекты запроса, особенно в случае выполнения нескольких сложных подзапросов.
Джейми Штраус
36

Вы можете использовать функцию load_only :

from sqlalchemy.orm import load_only

fields = ['name', 'addr', 'phone', 'url']
companies = session.query(SomeModel).options(load_only(*fields)).all()
Влад Безден
источник
1
Это решение является лучшим, поскольку оно по-прежнему работает как объект, а не только как список результатов.
rborodinov 02
Престижность вам за это решение. Он имеет множество преимуществ: - возвращает объект того же типа, что .first()и и .one()(который будет ленивым / нетерпеливым загружать поля и отношения), - может быть установлен как компонент запроса
Дэмиен
код чистый, но запрос sql выбирает все поля из базы данных. Я использовал, with_entitiesкак указано в принятом ответе, и запрос выбрал только эти поля /.
Шрикантх Джива
11

Вы можете использовать Model.query, потому что Model(или обычно его базовый класс, особенно в случаях, когда используется декларативное расширение) назначен Sesssion.query_property. В этом случае Model.queryэквивалентно Session.query(Model).

Я не знаю, как изменить столбцы, возвращаемые запросом (за исключением добавления дополнительных значений add_columns()).
Так что лучше всего использовать Session.query(Model.col1, Model.col2, ...)(как уже показал Салил).

фургон
источник
Я считаю, что также может быть способ сделать это со списком столбцов для значений запроса (), docs.sqlalchemy.org/en/latest/orm/… - но синтаксический сахар для списка в данный момент ускользает от меня.
JGFMK
3

Вы можете использовать Query.values, Query.values

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

gaozhidf
источник
-11

Пример здесь:

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

Я запрашиваю в БД фильмы с рейтингом <> 0, а затем сначала упорядочиваю их по рейтингу с самым высоким рейтингом.

Взгляните сюда: Select, Insert, Delete in Flask-SQLAlchemy

happygoat
источник