简体   繁体   English

针对视图的SQLAlchemy查询未返回完整结果

[英]SQLAlchemy query against a view not returning full results

I am using Flask-SQLAlchemy (flask_sqlalchemy==2.3.2) for my Flask webapp. 我在Flask Web应用程序中使用Flask-SQLAlchemy(flask_sqlalchemy == 2.3.2)。 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. 对于普通表查询,它的表现完美无缺,但是现在我正在过渡到将某些逻辑转换为SQL视图,而SQLAlchemy并未捕获全部结果。

This is my specific example: 这是我的具体示例:

SQL View view_ticket_counts : SQL视图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: 当我使用pgAdmin将其作为常规SQL查询运行时:

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: 但是,如果我像这样运行python SQLAlchemy查询:

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 它只打印一个结果: 1 1 3

So for some reason the SQLAlchemy query or implementation is only fetching the first element, even with .all() . 因此出于某种原因,即使使用.all() ,SQLAlchemy查询或实现也只获取第一个元素。

For completion this is my View Model class: 为了完成,这是我的View Model类:

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, . 您视图的实际键是event_id, price_id ,而不仅仅是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. 您只看到第一行的原因是,在查询模型对象/实体时,ORM会根据其主键为每个找到的行查询身份映射 ,并且如果对象已包含在结果中,则将其跳过。 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). 因此,在您处理第二行的情况下,SQLAlchemy发现具有主键1,的对象已经存在于结果中,并且仅忽略该行(因为不涉及任何加入的紧急加载)。

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" . 在ORM教程的“添加和更新对象”“合并的负载”下,提到并推理了这种隐式的“与众不同

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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