2010-07-19 31 views
1

我想实现一些在查询集额外的选择,并希望所需要的表添加到使用select_related方法查询表池,以便为“__”语法中受益。使用select_related和额外条款

这里是一个简单的模型的例子:

from django.db import models 

# Create your models here. 

class testA(models.Model): 
    code = models.TextField(unique = True) 
    date = models.DateTimeField(auto_now_add = True) 

class testB(models.Model): 
    text = models.TextField() 
    a = models.ForeignKey(testA) 

这里是我想建立查询:

SELECT (extract(hour from testa.date)) AS hour, testb.text FROM testb INNER JOIN testa ON (testb.a_id = testa.id) 

因此,这里是我如何建造起来的Python:

testB.objects.all().select_related('a').extra(select = {'hour' : 'extract(hour from testa.date)'}).values('hour','text') 

不过在Django删除他看到我没有使用“种皮”表(因为“价值”的时候select_related声明)。因此产生的SQL查询失败:

SELECT (extract(hour from testa.date)) AS "hour", "testb"."text" FROM "testb" 

如果我删除了“价值”的声明,它工作正常:

SELECT (extract(hour from testa.date)) AS "hour", "testb"."id", "testb"."text", "testb"."a_id", "testa"."id", "testa"."code", "testa"."date" FROM "testb" INNER JOIN "testa" ON ("testb"."a_id" = "testa"."id") 

但我必须把价值观声明,因为我想使聚集在“数按对象日期小时分组的b个对象“:

testB.objects.all().select_related('a').extra(select = {'hour' : 'extract(hour from testa.date)'}).values('hour').annotate(count = Count('pk')) 

那么实现这一目标的好方法是什么? “计算由另一个对象中的东西分组的对象”?或者是否有办法“强制”django保留“select_related”表格,即使他认为它们是无用的?

PS:我知道我可以使用额外的语句的“表”的说法,但在这种情况下,我将不得不重写我的加盟,我想

回答

1

我已经developped一个从Django的ORM受益Django应用程序来解决这种问题:django-cube。基本思想是模拟多维数据库,以便轻松计算聚合。

你需要(“__hour”:现场查找的“小时”)的functionnality没有实现,但实现它会采取可能15分钟。所以请阅读接下来的内容,它的工作原理等等,如果它符合你的需求,请写信给我,我会实施它。

主页上的示例和api文档不是最新的(他们将在几天内),但这些snippets是。如果你想给它一个尝试,这里是你将如何解决这个问题,Django的立方体:

#install the app first ... 
from cube.models import Dimension, Cube 

class MyCube(Cube): 
    #declare a dimension called 'hour_a', 
    #that is related to the field 'a__date__hour'. 
    hour_a = Dimension(field='a__date__hour') 

    #declare how to calculate the aggregation on a queryset 
    @staticmethod 
    def aggregation(queryset): 
     return queryset.count() 

然后,有各种方法来计算的结果,检查的片段...你可以例如使用:

cube(testB.objects.all()).measure_dict('hour_a', full=False) 

这将返回类似:

{ 
    12: {measure: 889}, 
    13: {measure: 6654}, 
    14: {measure: 77}, 
    #<hour>: <count> 
} 

而且,不走特色下载,而从源(分支0.3)退房。

我不知道什么是你真正的需要,这可能是你将不得不(它最初是用于数据可视化目的作出的)使用有点沉重。

+0

如果它最初是为了数据可视化而制作的,那正是我正在寻找的。我正在尝试构建的工具是一个允许用户通过“书写”这样的句子来查询数据库的工具:“我想要计算ObjectB.date> 20100101并且ObjectC.code ='foo'groupe的ObjectA通过ObjectA.code和ObjectC.category“ 用户界面是ajax,当用户选择要查询的第一个”模型“时,过滤器和按选项分组填充可能的值。 现在我正在尝试使用SQLAlchemy,但我会看看django-cube 谢谢 – 2010-07-20 07:50:04

0

我无法回答您的主要查询,但值得注意的是select_related__语法无关。 select_related只是一个优化,它将返回额外的相关对象,并在必要时向查询添加连接。但是用于查询相关表的双下划线语法可以使用或不使用select_related。

0

我在本地得到同样的错误:一切工作,直到“值”被追加,然后Django无法放置适当的FROM子句。我会将此示例发布到django-users组,并查看知情人员是否可以验证这是否是一个错误,或者是否有快速解决问题的方法。