我有以下模型,我正在使用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应用程序。
答案 0 :(得分:2)
注释in the Django documentation非常清楚:
注意:
order_by()调用中使用的任何字段都包含在SQL SELECT列中。当与distinct()一起使用时,这有时会导致意外结果。如果按相关模型中的字段排序,那些字段将添加到选定的列中,否则它们可能会使重复的行看起来不同。由于额外的列没有出现在返回的结果中(它们仅用于支持排序),因此有时看起来会返回非独特的结果。
同样,如果使用values()查询来限制所选列,则任何order_by()(或默认模型排序)中使用的列仍将涉及并可能影响结果的唯一性。
这里的道德是,如果你使用distinct(),请注意相关模型的排序。类似地,当同时使用distinct()和values()时,在按值()调用的字段排序时要小心。
另外,在下面:
这种指定字段名称(具有不同)的功能仅在PostgreSQL中可用。