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

时间:2019-07-10 21:32:41

标签: python postgresql sqlalchemy

我正在为Flask Web应用程序使用Flask-SQLAlchemy(flask_sqlalchemy == 2.3.2)。 对于普通表查询,它的表现完美无缺,但是现在我正在过渡到将某些逻辑制作到SQL视图中,而SQLAlchemy无法捕获全部结果。

这是我的具体示例:

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

当我使用pgAdmin将其作为普通SQL查询运行时

SELECT * FROM view_ticket_counts WHERE event_id=1

我得到结果:

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

但是,如果我像这样运行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)

它仅显示一个结果:1 1 3

因此出于某种原因,即使使用.all(),SQLAlchemy查询或实现也只获取第一个元素。

为完成此操作,这是我的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 个答案:

答案 0 :(得分:1)

您视图的实际键是event_id, price_id,而不仅仅是event_id,。您只看到第一行的原因是,在查询模型对象/实体时,ORM会根据其主键为每个找到的行查询identity map,并且如果对象已包含在结果中,它被跳过。因此,在您处理第二行的情况下,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)

"Adding and Updating Objects""Joined Load"下的ORM教程中提到并推理了这种隐式的“与众不同”。