2010-07-19 54 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組,並查看知情人員是否可以驗證這是否是一個錯誤,或者是否有快速解決問題的方法。