简体   繁体   中英

SQLAlchemy query against a view not returning full results

I am using Flask-SQLAlchemy (flask_sqlalchemy==2.3.2) for my Flask webapp. For normal table queries it has performed flawlessly, but now I am transitioning to making some of the logic into SQL Views and SQLAlchemy is not capturing the full results.

This is my specific example:

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

When I run this as a normal SQL query with pgAdmin:

SELECT * FROM view_ticket_counts WHERE event_id=1

I get the results:

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

However, if I run a python SQLAlchemy query like so:

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)

It only prints one result: 1 1 3

So for some reason the SQLAlchemy query or implementation is only fetching the first element, even with .all() .

For completion this is my View Model class:

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

Your view's actual key is event_id, price_id , not just event_id, . The reason why you are only seeing the first row is that when querying for model objects / entities the ORM consults the identity map for each found row based on its primary key, and if the object has already been included in the results, it is skipped. So in your case when the second row is processed, SQLAlchemy finds that the object with the primary key 1, already exists in the results, and simply ignores the row (since there is no joined eager loading involved).

The fix is simple:

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)

This sort of implicit "distinct on" is mentioned and reasoned about in the ORM tutorial under "Adding and Updating Objects" and "Joined Load" .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM