我想优化一个简单的 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'))
)
)
我看到的唯一选择是为这个相当简单的问题编写原始 SQL。
最佳答案
我会反过来做:您当前尝试检索所有传感器
,然后获取它们最新的关联记录
。为什么不检索具有 Sensor
的所有 Records
,使得 sensor.last_record_at == record.created
?
这样:
Records.objects.filter(sensor__last_record_at=F('created')).select_related('sensor')
可以完成这项工作。
这假设给定传感器永远不会同时有两条记录,否则,您可能会获得多次相同的 Sensor
,并且每个 Sensor
都有一个使用 last_record_at
日期记录
。
关于python - Django注释相关字段,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51986270/