2013-03-14 62 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里面使用。