2013-03-14 59 views
3

我有以下型號我敢用的SQLite3和MySQL測試:Django的:上最大的外鍵值選擇不同的值

# (various model fields extraneous to discussion removed...) 

class Run(models.Model): 
    runNumber = models.IntegerField() 

class Snapshot(models.Model): 
    t = models.DateTimeField() 

class SnapshotRun(models.Model): 
    snapshot = models.ForeignKey(Snapshot) 
    run = models.ForeignKey(Run) 
    # other fields which make it possible to have multiple distinct Run objects per Snapshot 

我想要一個查詢,這將給我一套runNumbers &快照的ID爲此,Snapshot.id低於某個指定的值。天真的我希望這個工作:

print SnapshotRun.objects.filter(snapshot__id__lte=ss_id)\ 
         .order_by("run__runNumber", "-snapshot__id")\ 
         .distinct("run__runNumber", "snapshot__id")\ 
         .values("run__runNumber", "snapshot__id") 

但是這打擊了

NotImplementedError: DISTINCT ON fields is not supported by this database backend 

兩個數據庫後端。不幸的是Postgres不是一個選項。

回退到原始SQL的時間?

更新

由於Django的ORM不會幫我出這個(感謝@jknupp)我還是設法得到以下原始SQL工作:

cursor.execute(""" 
      SELECT r.runNumber, ssr1.snapshot_id 
      FROM livedata_run AS r 
      JOIN livedata_snapshotrun AS ssr1 
      ON ssr1.id = 
      (
       SELECT id 
       FROM livedata_snapshotrun AS ssr2 
       WHERE ssr2.run_id = r.id 
        AND ssr2.snapshot_id <= %s 
       ORDER BY snapshot_id DESC 
       LIMIT 1 
      ); 
""", max_ss_id) 

這裏livedata 。在Django應用程序,這些表活在

+0

所以你希望它返回一個'runNumbers'列表,其中每行返回還包含附加到它的(衆多)'快照'ID列表? – 2013-03-14 19:39:11

+0

@ TimmyO'Mahony不完全;我想爲每次運行獲得一個'snapshot_id',最新的(但不超過'ss_id')。 – JohnJ 2013-03-14 20:03:42

回答

2

音符in the Django documentation是相當清楚的:

注意:

在SQL SELECT列中包含在order_by()調用中使用的任何字段。與distinct()結合使用時,有時會導致意想不到的結果。如果按照來自相關模型的字段進行排序,那些字段將被添加到選定列中,並且可能會使其他重複行看起來不同。由於額外的列不會出現在返回的結果中(它們僅用於支持排序),它有時看起來像是返回非重複結果。類似地,如果使用values()查詢來限制所選列,那麼在任何order_by()(或默認模型排序)中使用的列仍將涉及並可能影響結果的唯一性。

這裏的道德是,如果你使用distinct()注意相關模型的排序。類似地,將distinct()和values()一起使用時,請按not()調用中的字段進行排序時小心。

另外,低於:

指定字段名(具有鮮明的)這種能力只有在PostgreSQL裏面使用。