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

Snapshot.id が指定された値を下回っている一連の runNumbers とスナップショット 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 に答える