我正在为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)
答案 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教程中提到并推理了这种隐式的“与众不同”。