python - 用于返回最新并使用不同列的 flask-sqlalchemy 查询
问题描述
我真的很难在 flask-sqlalchemy 中编写我想要的正确 postgres 查询。
下面是我的数据的示例表。我正在尝试返回xxx
并获取每个唯一yyy
的最新(最新时间戳)。 name
所以理想情况下,对于下面的数据,我希望我的查询返回底部的 4 个条目。
+------------+-------+-----+--------------------------+
| name | xxx | yyy | time | ... (other columns)
+------------+-------+-----+--------------------------+
| aaa | 2 | 12 | 2021-03-11 20:27:13+00 |
| bbbb | 9 | 13 | 2021-03-11 20:27:13+00 |
| cccc | 2 | 16 | 2021-03-11 20:27:13+00 |
| dddd | 10 | 26 | 2021-03-11 20:27:13+00 |
| aaa | 4 | 13 | 2021-03-11 20:27:23+00 |
| bbbb | 8 | 12 | 2021-03-11 20:27:23+00 |
| cccc | 1 | 15 | 2021-03-11 20:27:23+00 |
| dddd | 12 | 26 | 2021-03-11 20:27:23+00 |
| aaa | 3 | 12 | 2021-03-11 20:27:33+00 |
| bbbb | 6 | 11 | 2021-03-11 20:27:33+00 |
| cccc | 1 | 17 | 2021-03-11 20:27:33+00 |
| dddd | 13 | 23 | 2021-03-11 20:27:33+00 |
+------------+-------+-----|--------------------------+
我最基本的返回最新的单个条目如下所示:
single_query = MyModel \
.query \
.filter_by(name = 'aaaa) \
.order_by(desc(MyModel.time)) \
.first()
使用我的模型,我试图通过如下查询(基于其他一些 SO 答案)来获得我的预期结果:
full_query = MyModel \
.query \
.with_entities(MyModel.name, MyModel.time, MyModel.xxx) \
.distinct(MyMmodel.name) \
.all()
这让我大部分时间都在那里,但它返回随机条目(似乎至少)。我以为我可以很容易地添加一个order_by(desc(MyModel.time))
,但我不能让它与上面的查询一起工作。
关于如何让它发挥作用的任何建议或一些让我朝着正确方向前进的建议?我一直在挠头一段时间。:)
我做了很多搜索,但不知道如何将这样的答案(SQLalchemy distinct, order_by different column)扩展到我的模型查询。
更新
如果我想一次查询两个表,例如通过sample_table_1
and ,我如何将 postgres 转换为 flask-sqlalchemy?sample_table_2
MyModel
MyModel2
实现我想要的原始查询如下:我能够基于@Oluwafemi Sule 的有用答案。我可以扩展这个或解决方案查询以满足我的需要:)
SELECT
m.name,
m.xxx,
m.yyy
n.xxx,
n.yyy
FROM (
SELECT
name,
xxx,
yyy,
ROW_NUMBER() OVER(PARTITION BY container_name ORDER BY time DESC) AS rn
FROM
sample_table_1
) m, (
SELECT
name,
xxx,
yyy,
ROW_NUMBER() OVER(PARTITION BY container_name ORDER BY time DESC) AS rn
FROM
sample_table_2
) n
WHERE m.container_name = n.container_name and m.rn = 1 and n.rn = 1;
解决方案
获得预期结果的 SQL 查询如下:
SELECT
name
,xxx
,yyy
,time
FROM
(
SELECT
name
,xxx
,yyy
,time
-- Number rows after partitioning by name and reverse chronological ordering
,ROW_NUMBER () OVER (PARTITION BY name ORDER BY time DESC) AS rn
FROM sample_table
) subquery
WHERE rn = 1;
现在,编写 SQLAlchemy 查询应如下所示:
from sqlalchemy import func
subquery = (
MyModel
.query
.with_entities(
MyModel.name,
MyModel.time,
MyModel.xxx,
MyModel.yyy,
func.row_number().over(
partition_by=MyModel.name,
order_by=MyModel.time.desc()
).label("rn")
)
)
full_query = (
MyModel.query.with_entities(
subquery.c.name,
subquery.c.time,
subquery.c.xxx,
subquery.c.yyy
)
.select_from(subquery)
.filter(subquery.c.rn == 1)
.all()
)
推荐阅读
- javascript - Javascript jQuery 函数没有定义变量
- ios - 关于如何从照片库中批量删除 iPhone 相册的任何想法?
- amazon-web-services - Kubernetes:AWS 集群自动扩缩器
- java - Swagger 生成的文件使用神秘的导入
- javascript - javascript - 如何仅将 13-14 英寸笔记本电脑屏幕的所有浏览器缩放级别降低到 80%?
- javascript - 检测集合中最靠近窗口的元素
- sql - 如何根据 fetch cteTable 更新某个字段
- google-analytics - 我是否需要在谷歌分析中为每个 android 应用程序创建一个属性?
- angular - 云构建不适用于不同的环境角度
- firebase - Firebase 部署错误“错误:函数未正确部署。”