Оператор Select, возвращающий только первую строку в результате - PullRequest
1 голос
/ 12 марта 2019

У меня есть следующий код:

@staticmethod
def get_all_locations_for_event(value):
   sql = text('SELECT * \
   FROM public.location_event \
   INNER JOIN public.location \
   ON public.location_event.location_id = public.location.id \
   WHERE event_id = :x;')
   result = db.engine.execute(sql, x = value)
   for r in result:
      dict_ = dict(r)
   return dict_

Возвращает только первый ряд. Однако я бы хотел вернуть все результаты. Я новичок в SQL-алхимии, так что прости меня, если я что-то упустил. Я искал в Интернете последние пару часов, и до сих пор я сталкивался только с примерами кода, которые возвращают одну строку, а не несколько строк.

Я знаю, что проблема связана с циклом for, так как он не выполняет итерации достаточное количество раз, чтобы получить оставшиеся данные, однако я не уверен, что в результате исправления будет получен объект.

P.S. Если это можно сделать с помощью метода ORM, я тоже весь в ушах. Я решил использовать SQL, потому что мне не удалось заставить мою модель ORM выбрать правильные данные.

Ответы [ 3 ]

2 голосов
/ 12 марта 2019

Ваш цикл for выполняет итерацию нужное количество раз, но в его теле вы повторно привязываете имя dict_ к новому экземпляру dict, и поэтому ваша функция возвращает самый последний результат, созданный вашим запросом.Вместо этого вы захотите вернуть список или превратить свою функцию в генератор:

def get_all_locations_for_event(value):
    ...
    result = db.engine.execute(sql, x = value)
    return result.fetchall()

В большинстве случаев нет необходимости явно преобразовывать экземпляры RowProxyрезультат до dict, так как они действуют как упорядоченные карты самостоятельно.Заметным исключением является сериализация в JSON, поскольку модуль json не знает, как обрабатывать прокси строк SQLAlchemy.

0 голосов
/ 12 марта 2019

Я предполагаю, что вы можете сделать что-то вроде (не проверено и зависит от вашей модели):

Location.join(LocationEvent).filter_by(event_id=**value**).all()

Для присоединения требуется соответствующий внешний ключ

0 голосов
/ 12 марта 2019

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

Если я не ошибаюсь, ваш результат уже является приписанным объектом (пожалуйста, исправьте меня, если я ошибаюсь в этом), то есть вы должны иметь доступ к соответствующим столбцам базы данных через точечную запись. Следовательно, вы должны иметь возможность циклически проходить через такие элементы, как:

Пример

dict_ = []

for r in result:
    id = r.id
    name = r.name
    dict_.append((id,name))
...