2012-02-26 10 views
7
私のDjangoのモデルでは

「行方不明」パディング出て、私は(例えば、サーバアラートが発生したとして)イベントの1回の発生を表し、非常に単純なモデルを持っている:週によってグループ化、週

class EventOccurrence: 
    event = models.ForeignKey(Event) 
    time = models.DateTimeField() 

私の最終目標は、過去に何回イベントが発生したかを示す表またはグラフを作成することです。n週。

だから私の質問は二つの部分があります:どのように私はtimeフィールドの週をgroup_byでき

  • を?
  • このgroup_byの結果を「パディングアウト」して、不足している週にゼロ値を追加するにはどうすればよいですか?たとえば、

、第二部のために、私はこのような結果を変換したい:

| week | count |     | week | count | 
| 2 | 3  |     | 2 | 3  | 
| 3 | 5  | —— becomes —> | 3 | 5  | 
| 5 | 1  |     | 4 | 0  | 
            | 5 | 1  | 

ジャンゴでこれを行うための最善の方法は何ですか?一般的なPythonソリューションもOKです。

答えて

4

DjangoのDateFieldなどdatetimeは週属性をサポートしていません。あなたがする必要がある1つのクエリですべて取得するために:私はそれらを結合することにより、複数のテーブルを照会する必要があるので

from django.db import connection 

cursor = connection.cursor() 
cursor.execute(" SELECT WEEK(`time`) AS 'week', COUNT(*) AS 'count' FROM %s GROUP BY WEEK(`time`) ORDER BY WEEK(`time`)" % EventOccurrence._meta.db_table, []) 

data = [] 
results = cursor.fetchall() 
for i, row in enumerate(results[:-1]): 
    data.append(row) 

    week = row[0] + 1 
    next_week = results[i+1][0] 
    while week < next_week: 
     data.append((week, 0)) 
     week += 1 
data.append(results[-1]) 

print data 
0

djangoクエリapi docを掘った後、私はdjango ORMシステムでクエリを作成する方法が見つかりませんでした。データベースのブランドは、MySQLの場合Cursorは、回避策です:

from django.db import connection, transaction 
cursor = connection.cursor() 

cursor.execute(""" 
    select 
     week(time) as `week`, 
     count(*) as `count` 
    from EventOccurrence 
    group by week(time) 
    order by 1;""") 

myData = dictfetchall(cursor) 

これは、私の意見では、最高のパフォーマンスソリューションです。しかし、これは欠けている週を埋めないことに気づく。あなたは、あなたが一日一日の日付を取るとPythonを経由して、それを集計する必要があり、データベースのブランドの独立コードを探しているなら

は、Python(以下、パフォーマンス)

経由 Indepedentデータベースブランドのソリューションを編集しました。これはあなたのケースのコードであればルックスのようなことがあります。

#get all weeks: 
import datetime 
weeks = set() 
d7 = datetime.timedelta(days = 7) 
iterDay = datetime.date(2012,1,1) 
while iterDay <= datetime.now(): 
    weeks.add(iterDay.isocalendar()[1]) 
    iterDay += d7 

#get all events 
allEvents = EventOccurrence.objects.value_list('time', flat=True) 

#aggregate event by week 
result = dict() 
for w in weeks: 
    result.setdefault(w ,0) 

for e in allEvents: 
    result[ e.isocalendar()[1] ] += 1 

(免責事項:テストされていません)

0

を、私は、これらの要件を解決するために、DBのビューを使用しています。

CREATE VIEW my_view 
    AS 
    SELECT 
    *, // <-- other fields goes here 
    YEAR(time_field) as year, 
    WEEK(time_field) as week 
    FROM my_table; 

とモデル:

from django.db import models 

class MyView(models.Model): 
    # other fields goes here 
    year = models.IntegerField() 
    week = models.IntegerField() 

    class Meta: 
     managed = False 
     db_table = 'my_view' 

    def query(): 
     rows = MyView.objects.filter(week__range=[2, 5]) 
     # to handle the rows 

「穴」週/月のためのパディングを0に@danihpによる方法を使用して、このデシベルビューから行を取得した後。

注:これはMySQLバックエンドでのみテストされています.Microsoft SQL ServerなどでOKかどうかはわかりません。

関連する問題