如何对返回 orm 对象和自定义列的元组的查询进行正确排序、分组?
Posted
技术标签:
【中文标题】如何对返回 orm 对象和自定义列的元组的查询进行正确排序、分组?【英文标题】:How do I sort, group a query properly that returns a tuple of an orm object and a custom column? 【发布时间】:2011-08-05 19:50:57 【问题描述】:我正在寻找一种方法来获得一个返回元组的查询,该元组首先按列排序,然后按另一个(按该顺序)分组。只是.sort_by().group_by()
似乎不起作用。现在我尝试了以下,导致返回值出错(我只是得到了 orm 对象,而不是初始元组),但请自己阅读:
基本场景:
有一个查询通过外键查询从test3
表链接的测试orm 对象。
此查询还返回一个名为linked
的列,其中包含true
或false
。它最初是未分组的。
my_query = session.query(test_orm_object)
... lots of stuff like joining various things ...
add_column(..condition that either puts 'true' or 'false' into the column..)
所以原始返回值是一个元组(orm 对象,另外还有真/假列)。
现在这个查询应该为测试 orm 对象分组(所以 test.id
列),但在此之前,按链接列排序,因此在分组期间首选带有 true
的条目。
假设当前未排序、未分组的查询存储在 my_query 中,我的实现方法是:
# Get a sorted subquery
tmpquery = my_query.order_by(desc('linked')).subquery()
# Read the column out of the sub query
my_query = session.query(tmpquery).add_columns(getattr(tmpquery.c,'linked').label('linked'))
my_query = my_query.group_by(getattr(tmpquery.c, 'id')) # Group objects
运行时生成的 SQL 查询是(顺便说一句,它看起来很好 - 子查询 'anon_1
' 在自身内部正确排序,然后提取并提取其 id 以及 'linked
' 列(其中SQLAlchemy 显然想要的其他几列),并且结果被正确分组):
SELECT anon_1.id AS anon_1_id, anon_1.name AS anon_1_name, anon_1.fk_test3 AS anon_1_fk_test3, anon_1.linked AS anon_1_linked, anon_1.linked AS linked
FROM (
SELECT test.id AS id, test.name AS name, test.fk_test3 AS fk_test3, CASE WHEN (anon_2.id = 87799534) THEN 'true' ELSE 'false' END AS linked
FROM test LEFT OUTER JOIN (SELECT test3.id AS id, test3.fk_testvalue AS fk_testvalue
FROM test3)
AS anon_2 ON anon_2.fk_testvalue = test.id ORDER BY linked DESC
)
AS anon_1 GROUP BY anon_1.id
我在 phpmyadmin 中对其进行了测试,正如预期的那样,它给了我 id 列(用于 orm 对象 id),然后是 SQL_Alchemy 似乎想要的附加列,以及链接列。到目前为止,一切顺利。
现在我的预期返回值将是,因为它们来自原始未排序、未分组的查询:
A tuple: 'test' orm object (anon_1.id column), 'true'/'false' value (linked column)
然而,新的排序/分组查询的实际返回值是(在应用上述代码之前,原始查询确实返回了一个 touple): 仅“测试” orm 对象
为什么会这样,我该如何解决?
如果这种方法被证明有些缺陷,请见谅。 我真正想要的是,简单地对原始查询进行排序,然后在不触及返回值的情况下进行分组。正如您在上面看到的,我的尝试是再次“恢复”额外的返回值,但这没有奏效。如果这种方法根本上是错误的,我应该怎么做?
子查询使用说明:
整个子查询的重点是强制 SQLAlchemy 作为第一步单独执行这个查询。
我想先对结果进行排序,然后对有序的结果进行分组。这似乎很难一步正确地完成(当使用 SQL 手动尝试时,我遇到了我想要的一步组合 order 和 group by 的问题)。
所以我不是简单的排序、分组,而是先排序,然后子查询强制先执行排序步骤,然后再分组。
从使用生成的 SQL 的手动 PHPMyAdmin 测试来看,这似乎工作正常。实际问题是原始查询(现在被包装为您感到困惑的子查询)添加了一个列,现在通过将其包装为子查询,该列从整体结果中消失了。我尝试将其读取到外包装失败。
【问题讨论】:
一点实际代码,为了简洁而精简,在这里会有所帮助。特别是说 session.query(session.query(...).subquery()) 似乎有点奇怪,因为我看不到它是如何完成任何事情的,然后 add_columnns(cols that are in the subquery?)跨度> 【参考方案1】:如果您提供示例会更好。我不知道这些列是在单独的表中还是不在。看看你的第一段,我会做这样的事情:
a = session.query(Table1, Table2.column).\
join(Table2, Table1.foreign_key == Table2.id).\
filter(...).group_by(Table2.id).order_by(Table1.property.desc()).all()
我不知道你到底想做什么,因为我需要查看你的实际模型,但它应该看起来像这样,可能是表/对象翻转或更多过滤器。
【讨论】:
以上是关于如何对返回 orm 对象和自定义列的元组的查询进行正确排序、分组?的主要内容,如果未能解决你的问题,请参考以下文章