Django:在最大外键值上选择不同的值

时间:2013-03-14 18:22:06

标签: python mysql django

我有以下模型,我正在使用SQLite3和MySQL进行测试:

# (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& Snapshot.id低于某个指定值的快照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应用程序。

1 个答案:

答案 0 :(得分:2)

注释in the Django documentation非常清楚:

  

注意:

     

order_by()调用中使用的任何字段都包含在SQL SELECT列中。当与distinct()一起使用时,这有时会导致意外结果。如果按相关模型中的字段排序,那些字段将添加到选定的列中,否则它们可能会使重复的行看起来不同。由于额外的列没有出现在返回的结果中(它们仅用于支持排序),因此有时看起来会返回非独特的结果。

     

同样,如果使用values()查询来限制所选列,则任何order_by()(或默认模型排序)中使用的列仍将涉及并可能影响结果的唯一性。

     

这里的道德是,如果你使用distinct(),请注意相关模型的排序。类似地,当同时使用distinct()和values()时,在按值()调用的字段排序时要小心。

另外,在下面:

  

这种指定字段名称(具有不同)的功能仅在PostgreSQL中可用。