在 sqlalchemy 中按 row_number 过滤
Posted
技术标签:
【中文标题】在 sqlalchemy 中按 row_number 过滤【英文标题】:filter by row_number in sqlalchemy 【发布时间】:2016-11-04 17:44:54 【问题描述】:如何在以下查询中过滤 row_number ==1:
query = session.query(Foo, func.row_number().over(
partition_by=Foo.foo_field, order_by=desc(Foo.foo_date_time)).label("row_number"))
query = query.filter(Foo.time_key <= time_key)
# query = query.filter(row_number == 1)
result = query.all()
【问题讨论】:
【参考方案1】:我找到了:
row_number_column = func.row_number().over(partition_by=Foo.foo_field, order_by=desc(Foo.foo_date_time)).label('row_number')
query = self.session.query(Foo)
query = query.filter(Foo.time_key <= time_key)
query = query.add_column(row_number_column)
query = query.from_self().filter(row_number_column == 1)
【讨论】:
【参考方案2】:也可以使用子查询来完成:
sub_query = session.query(
Foo,
func.row_number().over(partition_by=Foo.foo_field, order_by=desc(Foo.foo_date_time)).label("row_number")
)
sub_query = sub_query.filter(Foo.time_key <= time_key).subquery()
query = session.query(sub_query).filter(sub_query.c.row_number == 1)
它基本上生成一个等效的 SQL 语句,就像将 row_number 添加为列一样。
编译语句。
sub_query = session.query(
Foo,
func.row_number().over(partition_by=Foo.foo_field, order_by=desc(Foo.foo_date_time)).label("row_number")
)
sub_query = sub_query.filter(Foo.time_key <= time_key).subquery()
query = session.query(sub_query).filter(sub_query.c.row_number == 1)
str(query.statement.compile())
将生成以下内容:
-- SubQuery function
SELECT anon_1.time_key,
anon_1.foo_field,
anon_1.foo_date_time,
anon_1.row_number
FROM (
SELECT foo.time_key AS time_key,
foo.foo_field AS foo_field,
foo.foo_date_time AS foo_date_time,
row_number() OVER (PARTITION BY foo.foo_field ORDER BY foo.foo_date_time DESC) AS row_number
FROM foo
WHERE foo.time_key <= %(time_key_1)s
) AS anon_1
WHERE anon_1.row_number = %(row_number_1)s
UPDATE:请记住,Query.from_self 方法自 SQLAlchemy 1.4 起已弃用,并将在 2.0 中删除 according to the official documentation
如果有人在使用,可以查看migration guide for this case
【讨论】:
以上是关于在 sqlalchemy 中按 row_number 过滤的主要内容,如果未能解决你的问题,请参考以下文章
在 graphene-sqlalchemy 查询中按 id 过滤
如何在 Flask SQLAlchemy 中按多个条件进行过滤?