SQLAlchemy запрос к представлению не возвращает полных результатов - PullRequest
0 голосов
/ 11 июля 2019

Я использую Flask-SQLAlchemy (flask_sqlalchemy == 2.3.2) для моего веб-приложения Flask. Для обычных табличных запросов это было выполнено безупречно, но сейчас я перехожу к превращению некоторой логики в представления SQL, и SQLAlchemy не собирает полные результаты.

Это мой конкретный пример:

SQL View view_ticket_counts:

CREATE VIEW view_ticket_counts AS
SELECT event_id, price_id, COUNT(1) AS ticket_count FROM public.tickets
GROUP BY event_id, price_id

Когда я запускаю это как обычный SQL-запрос с pgAdmin:

SELECT * FROM view_ticket_counts WHERE event_id=1

Я получаю результаты:

|event_id|price_id|ticket_count|
|   1    |    1   |     3      |
|   1    |    2   |     1      |

Однако, если я выполню SQLAlchemy-запрос на python, вот так:

ticket_counts = ViewTicketCounts.query.filter_by(event_id=1).all()
for tc in ticket_counts:
    print(tc.event_id, tc.price_id, tc.ticket_count)

Он печатает только один результат: 1 1 3

По какой-то причине запрос или реализация SQLAlchemy извлекает только первый элемент, даже с .all().

Для завершения это мой класс View Model:

class ViewTicketCounts(db.Model):
    event_id = db.Column(BigInteger, primary_key=True)
    price_id = db.Column(BigInteger)
    ticket_count = db.Column(BigInteger)

1 Ответ

1 голос
/ 11 июля 2019

Фактический ключ вашего представления event_id, price_id, а не просто event_id,.Причина, по которой вы видите только первую строку, заключается в том, что при запросе объектов / сущностей модели ORM обращается к карте идентификации для каждой найденной строки на основе своего первичного ключа, и если объект уже был включен врезультаты, это пропущено.Таким образом, в вашем случае, когда обрабатывается вторая строка, SQLAlchemy обнаруживает, что объект с первичным ключом 1, уже существует в результатах, и просто игнорирует строку (так как в этом не участвует присоединенная активная загрузка).

Исправление простое:

class ViewTicketCounts(db.Model):
    event_id = db.Column(BigInteger, primary_key=True)
    price_id = db.Column(BigInteger, primary_key=True)
    ticket_count = db.Column(BigInteger)

Этот тип неявного «отличного включения» упоминается и обосновывается в руководстве по ORM под «Добавление и обновление объектов» и »Объединенная нагрузка ".

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...