如何对返回 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 的列,其中包含truefalse。它最初是未分组的。

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 对象和自定义列的元组的查询进行正确排序、分组?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Django 数据库查询中查询列的元组?

在元组的ndarray中查找元组并返回搜索到的元组的索引

选择包含混合单引号和双引号的元组的查询

扁平化包和元组的元组

编程里面元组和数组的区别是啥?

Pyspark:如何将现有非空列的元组列表作为数据框中的列值之一返回