我想优化一个简单的Django查询以预取所有最新值。
sensors = Sensor.objects.all()
这是模型:
class Sensor:
last_record_at = models.DateTimeField(null=True, blank=True)
class Record:
value = models.FloatField()
sensor = models.ForeignKey('hardware.Sensor', on_delete=models.CASCADE)
created = models.DateTimeField(auto_now_add=True)
之前,Sensor模型具有要记录的外键(最后一条记录),只需添加以下内容即可检索所有记录:
.select_related('last_record')
为了优化数据库,我删除了该外键,并将其替换为名为last_record_at的日期时间字段。
我正在使用Django 2.0,我想知道是否存在一种漂亮的ORM方法,可以使用子查询,批注或预取来检索一个(或两个)查询中的所有传感器和最后记录。
类似的东西(不起作用):
record_sub_query = Record.objects.filter(
created=OuterRef('last_record_at'),
sensor_id=OuterRef('pk')
)
sensors = Sensor.objects.all().annotate(
last_record=Subquery(record_sub_query[:1])
)
或使用预取:
sensors = Sensor.objects.all().prefetch_related(
Prefetch(
'records',
queryset=Record.objects.filter(created=F('sensor__last_record_at'))
)
)
我看到的唯一选择是针对这个相当简单的问题编写Raw SQL。
答案 0 :(得分:1)
相反,我会这样做:您当前尝试检索所有<h2>Userstories</h2>
<button (click)="onNewStory()">New Story</button>
<table>
<tr *ngFor="let story of userstories" (click)="onUpdate(story)" [class.selected]="story === selectedStory">
<td>{{story.id}}</td>
<td>{{story.name}}</td>
<td><button (click)="onUpdate(story)">Click me!</button></td>
</tr>
</table>
<app-userstory-detail [story]="selectedStory"></app-userstory-detail>
,然后获取其最新关联的Sensors
。为什么不检索具有Record
这样的Records
的所有Sensor
?
这种方式:
sensor.last_record_at == record.created
会做这份工作。
这假设对于给定的传感器,您永远不会同时有两个记录,否则,您可能会得到相同的Records.objects.filter(sensor__last_record_at=F('created')).select_related('sensor')
数倍,并且每个Sensor
都有一个Sensor
Record
日期。