我正在寻找一种方法来获得一个查询,该查询返回一个首先按列排序的元组,然后按另一个按顺序分组(按此顺序)。简单地.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对象,另外还有true / false列)。
现在应该为测试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查询是(它看起来很顺便btw - 子查询“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)
然而,新的有序/分组查询的实际返回值是(原始查询确实在应用上面的代码之前返回了一个句子): 'test'allm object only
为什么会这样,我该如何解决?
对不起,如果这种方法有点瑕疵。 我真正想要的是,将原始查询简单地排序,然后分组而不触及返回值。正如您在上面所看到的,我的尝试是再次“恢复”额外的返回值,但这不起作用。如果这种方法根本错误,我应该怎么办?
子查询使用说明:
整个子查询的要点是强制SQLAlchemy作为第一步单独执行此查询。
我想首先订购结果,然后将订购的结果分组。这似乎很难在一个步骤中正确完成(当使用SQL手动尝试时,我按照我想要的步骤将组合顺序和组合出现问题)。
因此,我不是简单地订购,分组,而是先订购,然后再查询,以强制执行订单步骤,然后将其分组。
从使用生成的SQL的手动PHPMyAdmin测试判断,这似乎工作正常。实际问题是原始查询(现在被包装为您感到困惑的子查询)有一个添加的列,现在通过将其作为子查询包装起来,该列已从整体结果中消失。我试图把它读到外包装上失败了。
答案 0 :(得分: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()
我不确切地知道你要做什么,因为我需要查看你的实际模型,但它看起来应该是这样的,可能是桌面/ objs翻转或更多过滤器。