2009-03-04 13 views
1

は、Djangoのクエリセットオブジェクトを使用してこの問合せをリライトする方法があるの参加:ジャンゴ1.0/1.1リライトは

SELECT b.created_on, SUM(a.vote) 
FROM votes a JOIN votes b ON a.created_on <= b.created_on 
WHERE a.object_id = 1 
GROUP BY 1 
が 票は表がある

、OBJECT_IDが複数回(外部キーを発生intです - それはここでは関係ありませんが)、および日時であるcreated_on。

FWIWでは、このクエリを使用すると、過去の任意の時点で、そのobject_idの以前の投票をすべて集計することができます。

答えて

1

Django ORMでクエリを作成できないことは間違いありません。新しいDjango集約コードはかなり柔軟ですが、私はそれがあなたが望むものを正確に行うことはできないと思います。

本当にクエリが機能しますか? b.object_idが1であることを確認していないようです。

このコードはうまくいくはずですが、1行以上で効率的ではありません。

集約はトランクでのみ使用できるため、djangoのインストールを更新する必要があります。

+0

おそらくあなたにはおそらく最も近い可能性がありますが、あなたの言うとおり、非効率です。 私はSQLを直接.extra()を使って実行することに決めました。 –

0

集約は問題ではありません。ここでの問題は、DjangoのORMは、AFAIKというForeignKeyではないものの結合を単純にしないということです。

0

これは私が今使っているものです。皮肉なことに、SQLは壊れていますが、これはその要点です:

def get_score_over_time(self, obj): 
    """ 
    Get a dictionary containing the score and number of votes 
    at all times historically 
    """ 
    import pdb; pdb.set_trace(); 
    ctype = ContentType.objects.get_for_model(obj) 
    try: 
     query = """SELECT b.created_on, SUM(a.vote) 
         FROM %s a JOIN %s b 
         ON a.created_on <= b.created_on 
         WHERE a.object_id = %s 
         AND a.content_type_id = %s 
         GROUP BY 1""" % (
      connection.ops.quote_name(self.model._meta.db_table), 
      connection.ops.quote_name(self.model._meta.db_table), 
      1, 
      ctype.id, 
      ) 
     cursor = connection.cursor() 
     cursor.execute(query) 
     result_list = [] 
     for row in cursor.fetchall(): 
      result_list.append(row) 
    except models.ObjectDoesNotExist: 
     result_list = None 
    return result_list