使用窗口函数在 Postgres 上使用 SqlAlchemy 限制查询
Posted
技术标签:
【中文标题】使用窗口函数在 Postgres 上使用 SqlAlchemy 限制查询【英文标题】:Using window functions to LIMIT a query with SqlAlchemy on Postgres 【发布时间】:2013-07-02 23:14:39 【问题描述】:我正在尝试使用 sqlalchemy ORM 编写以下 sql 查询:
SELECT * FROM
(SELECT *, row_number() OVER(w)
FROM (select distinct on (grandma_id, author_id) * from contents) as c
WINDOW w AS (PARTITION BY grandma_id ORDER BY RANDOM())) AS v1
WHERE row_number <= 4;
这是我到目前为止所做的:
s = Session()
unique_users_contents = (s.query(Content).distinct(Content.grandma_id,
Content.author_id)
.subquery())
windowed_contents = (s.query(Content,
func.row_number()
.over(partition_by=Content.grandma_id,
order_by=func.random()))
.select_from(unique_users_contents)).subquery()
contents = (s.query(Content).select_from(windowed_contents)
.filter(row_number >= 4)) ## how can I reference the row_number() value?
result = contents
for content in result:
print "%s\t%s\t%s" % (content.id, content.grandma_id,
content.author_id)
如您所见,它几乎是建模的,但我不知道如何从外部查询 where 引用子查询的 row_number()
结果。我尝试了类似windowed_contents.c.row_number
并在窗口函数上添加label()
调用,但它不起作用,在官方文档或*** 中找不到任何类似的示例。
如何做到这一点?另外,您能否建议一种更好的方法来进行此查询?
【问题讨论】:
【参考方案1】:windowed_contents.c.row_number
与 label()
是你的做法,对我有用(注意 select_entity_from()
方法是 SQLA 0.8.2 中的新方法,在 0.9 与 select_from()
中需要):
from sqlalchemy import *
from sqlalchemy.orm import *
from sqlalchemy.ext.declarative import declarative_base
Base = declarative_base()
class Content(Base):
__tablename__ = 'contents'
grandma_id = Column(Integer, primary_key=True)
author_id = Column(Integer, primary_key=True)
s = Session()
unique_users_contents = s.query(Content).distinct(
Content.grandma_id, Content.author_id).\
subquery('c')
q = s.query(
Content,
func.row_number().over(
partition_by=Content.grandma_id,
order_by=func.random()).label("row_number")
).select_entity_from(unique_users_contents).subquery()
q = s.query(Content).select_entity_from(q).filter(q.c.row_number <= 4)
print q
【讨论】:
func.row_number().over(...
在 0.5 版本中不起作用,所以解决方法?
0.5 于六年前发布。升级?否则,text("ROW NUMBER OVER")
或类似的文本形式可能是您最直接的途径。以上是关于使用窗口函数在 Postgres 上使用 SqlAlchemy 限制查询的主要内容,如果未能解决你的问题,请参考以下文章
如何在带有 Postgres 的动态框架中使用窗口函数中的列值?
使用'parititon by'和窗口函数在postgres中返回多于一行?