3

我正在使用 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 和快照 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 应用程序。

4

1 回答 1

2

Django 文档中的注释非常清楚:

笔记:

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

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

这里的寓意是,如果您使用 distinct() 小心按相关模型排序。同样,当一起使用 distinct() 和 values() 时,在按不在 values() 调用中的字段排序时要小心。

此外,在此之下:

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

于 2013-03-14T20:39:26.857 回答