2017-10-11 3 views
0

postgres에 대한 확장자 인 timescaledb을 사용하고 있습니다. 여기에는 time_bucket이라는 SQL 함수가 있습니다.Django ORM Queryset에 사용자 정의 SQL 함수 (date_trunc와 유사) 주석 달기

SELECT 
    time_bucket('1 minute', time) AS tb, 
    AVG(s0) 
FROM measurements 
WHERE 
    time >= to_timestamp(1) AND 
    time <= to_timestamp(2) 
GROUP BY tb 
ORDER BY tb ASC; 

models.py :

class Measurement(models.Model): 

    device_id = models.IntegerField(primary_key=True) 
    time = models.DateTimeField() 
    s0 = models.FloatField(blank=True, null=True) 
    s1 = models.FloatField(blank=True, null=True) 

내 지금까지 시도 :

class TimeBucket(Func): 

    function = 'time_bucket' 
    template = '%(function)s(\'{bucket_width}\', %(expressions)s)'.format(bucket_width='1 minute') 


(Measurement.objects 
    .values('time') 
    .annotate(tb=TimeBucket('time')) 
    .annotate(s_desc=Avg('s0')) 
    .filter(
     time__gte=datetime.fromtimestamp(start), 
     time__lte=datetime.fromtimestamp(end)) 
    .order_by('tb') 
) 

결과를 다음과 같이 나는 쿼리를 생성하는 ORM와 함께이 기능을 사용하려면 입력 :

SELECT 
    "measurements"."time", 
    time_bucket('1 minute', "measurements"."time") AS "tb", 
    (AVG("measurements"."s0")) AS "s_desc" 
FROM "measurements" 
WHERE (
    "measurements"."time" <= 2447-10-02 14:17:01+00:00 AND 
    "measurements"."time" >= 1970-01-01 00:00:01+00:00 
) 
GROUP BY "measurements"."time", time_bucket('1 minute', "measurements"."time") 
ORDER BY "tb" ASC 

당신이 왼쪽 두 추한 지점이보다시피 : 어떻게 그것을 반복하는 대신 GROUP BY에 별명 tb를 사용할 수

  • ?
  • time_buckets0 만 쿼리하면됩니다. 검색어를 해독하지 않고 time을 제거하는 방법?

답변

1

집계 기능을 사용하기 전에 잘린 값 주석을 .values() (예 : .values('tb'))에 사용해야합니다.

장고 1.11
qs = (
    Measurement.objects 
    .filter(...) 
    .annotate(tb=TimeBucket('time')) 
    .values('tb') 
    .annotate(s_desc=Avg('s0')) 
    .order_by('tb') 
) 

.annotate(tb=TimeBucket('time')) 
.values('tb') 

.values(tb=TimeBucket('time')) 
에 선을 더 DRY 용액을 사용하여 조합 될 수있다