2010-07-19 3 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, когда видит, что я не использую таблицу testa (из-за «значений», заявление). Таким образом, в результате 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") 

, но я должен положить заявление значения, как я хочу, чтобы агрегаты, как и в «кол объекты б сгруппированных в час дня в объекте»:

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

Так что это хороший способ для того чтобы достигнуть этого? «Считать объекты, сгруппированные чем-то в другом объекте»? Или есть способ «заставить» джанго сохранить таблицы «select_related», даже если он считает их бесполезными?

PS: Я знаю, что я мог бы использовать «таблицы» аргумент дополнительного заявления, но в этом случае я бы переписать присоединиться сам, и я хочу, чтобы извлечь выгоду из Джанго ОРМ

ответ

1

Я разработана Приложение Django для решения таких проблем: django-cube. Основная идея состоит в том, чтобы эмулировать многомерную БД, чтобы легко вычислить агрегации.

Функциональность, которую вы требуете ('__hour': поиск в поле «час») не реализован, но реализация этого займет, вероятно, 15 минут. Так что читайте, что будет дальше, как это работает и т. Д. ... и если это вам подходит, напишите мне, и я его реализую.

Примеры на главной странице и в api doc не обновляются (они будут через несколько дней), но это snippets. Если вы хотите, чтобы дать ему попробовать, вот как вы бы решить эту проблему с помощью Джанго-куба:

#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

Если это было сделано для визуализации данных, это именно то, что я ищу. Инструмент, который я пытаюсь создать, - это инструмент, позволяющий пользователям запрашивать базу данных путем «написания» предложений следующим образом: «Я хочу подсчитать ObjectA с ObjectB.date> 20100101 и иметь ObjectC.code = 'foo' groupe по ObjectA.code и ObjectC.category " Пользовательский интерфейс является ajax, и когда пользователь выбирает первую« модель »для запроса, фильтры и группы по выбору заполняются возможными значениями. На данный момент я пытаюсь с SQLAlchemy, но я посмотрю на django-cube Спасибо –

0

Я не могу ответить на ваш основной запрос, но стоит отметить, что select_related не имеет ничего общего с синтаксисом __. select_related - это просто оптимизация, которая будет возвращать дополнительные связанные объекты, добавляя при необходимости добавления к запросу. Но синтаксис двойного подчеркивания для запроса связанных таблиц работает с или без select_related.

0

Я получаю ту же ошибку локально: все работает до тех пор, пока не будут добавлены «значения», а затем django не сможет разместить соответствующее предложение FROM. Я бы разместил этот пример в группе django-users и посмотрел, может ли кто-то из знакомых проверить, является ли это ошибкой, или если есть необходимость исправить ошибку.

Смежные вопросы