我可以在django 1.3的orm中控制GROUP BY吗?

moc*_*ect 5 python mysql django orm django-orm

我认为最好用一个例子来解释.

这是数据的样子:

|project            |
|id|name            |
|1 |some project    |
|2 |my other project|

|run                                  |
|id|project_id|start_time   |result   |
|1 |1         |1305732581845|something|
|2 |1         |1305732593721|nothing  |
|3 |2         |1305732343721|nothing  |
|4 |2         |1305732556821|something|
Run Code Online (Sandbox Code Playgroud)

我希望能够从项目的每个最新运行中获得整个记录集.SQL Query看起来像这样:

SELECT *, MAX("run"."start_time")
FROM "run"    
LEFT OUTER JOIN "project" ON ("run"."project_id" = "project"."id") 
GROUP BY "project"."id"
Run Code Online (Sandbox Code Playgroud)

这将返回两个表中所有列的最新项目运行,这很棒,这正是我需要的.

所以在尝试在django 1.3中找到django orm等价物时,我根本找不到合适的方法来做到这一点.如果我做这样的事情:

Run.objects.annotate(Max('start_time'))
Run Code Online (Sandbox Code Playgroud)

生成的SQL查询将类似于:

SELECT 
"run"."id", "run"."result", "run"."project_id", "project"."id", "project"."name", 
MAX("run"."start_time")
FROM "run"
LEFT OUTER JOIN "project" ON ("run"."project_id" = "project"."id")
GROUP BY "run"."id", "run"."result", "run"."project_id", "project"."id", "project"."name"
Run Code Online (Sandbox Code Playgroud)

这不会返回正确的结果,因为group by不符合我的要求.我相信在以前版本的django中,以下内容可以在查询中正确明确地设置group by子句,但似乎在1.3中不起作用:

q = Run.objects.annotate(Max('start_time'))
q.query.group_by = [("project", "id")]
Run Code Online (Sandbox Code Playgroud)

在1.3中,这将生成完全相同的查询,而不是手动修改查询中的group_by属性.

我还在annotate()调用之前和之后基于记录的.values()行为的逻辑方式尝试了这种方法,但它没有按预期工作.当我尝试这个时:

q = Run.objects.values('project__id').annotate(Max('start_time')).values('id')
Run Code Online (Sandbox Code Playgroud)

我最终得到了这样的查询:

SELECT 
"run"."id", "run"."project_id"
MAX("run"."start_time")
FROM "run"
LEFT OUTER JOIN "project" ON ("run"."project_id" = "project"."id")
GROUP BY "run"."id", "run"."project_id"
Run Code Online (Sandbox Code Playgroud)

任何人都可以指出我正确的方式做我正在做的事情没有以下任何一件事:

  • 使用原始SQL - 当我经常不得不生成自己的查询时,使用orm会有什么意义?
  • 使用.extra(select = {'latest':'somequery'}) - 当没有子查询的完全有效的查询可以给我我想要的东西时,为什么我必须使用子查询.
  • 使用多个查询来获取相同的数据 - 再次,为什么我必须进行多次查询才能获得1中可用的结果?

moc*_*ect 1

tl;dr:Django 确实允许您控制 group by 子句,但它限制它在所有类型的 SQL 上工作,所以我不能做我想做的事。

有人向我指出,我尝试使用 django ORM 生成的原始查询实际上并不适用于所有类型的 SQL。这是我正在寻找的查询的回顾:

SELECT *, MAX("run"."start_time")
FROM "run"    
LEFT OUTER JOIN "project" ON ("run"."project_id" = "project"."id") 
GROUP BY "project"."id"
Run Code Online (Sandbox Code Playgroud)

如果一个人尝试选择不在 MSSQL 中的 GROUP BY 中的内容,他们实际上会收到错误。所以在我看来,django 实际上不应该让我生成这样的查询,我本质上是在尝试错误地解决我的问题。