python - Django注释相关字段

标签 python django orm

我想优化一个简单的 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/

相关文章:

java - 如何从没有主键的连接表中创建实体

c# - Entity Framework 对于小型企业应用程序来说会不会太过分了?

python - 谷歌应用引擎: Using Ajax

python - 如何使用 API 从 Google 文档中提取标题

python - 如何使用 Tesseract API 迭代单词?

python - 使用 MySQL 的 Django Web 框架从请求对象获取数据

python - 为什么此日志记录配置不打印到标准输出?

javascript - 带有 Python 表条目的简单用户 Web 界面

python - "ImportError: DLL load failed while importing _openmp_helpers"?

python - 为 MySQL View 创建模型并加入它