簡體   English   中英

Django:在最大外鍵值上選擇不同的值

[英]Django: Selecting distinct values on maximum foreign key value

我有以下模型,我正在使用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應用程序。

Django文檔中的注釋非常清楚:

注意:

order_by()調用中使用的任何字段都包含在SQL SELECT列中。 當與distinct()一起使用時,這有時會導致意外結果。 如果按相關模型中的字段排序,那些字段將添加到選定的列中,否則它們可能會使重復的行看起來不同。 由於額外的列不會出現在返回的結果中(它們僅用於支持排序),因此有時看起來會返回非獨特的結果。

同樣,如果使用values()查詢來限制所選列,則仍將涉及任何order_by()(或默認模型排序)中使用的列,這可能會影響結果的唯一性。

這里的道德是,如果你使用distinct(),請注意相關模型的排序。 類似地,當同時使用distinct()和values()時,在按值()調用的字段排序時要小心。

另外,在下面:

這種指定字段名稱(具有不同)的功能僅在PostgreSQL中可用。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM