我正在为水文学家写网页界面。水文学家应该看到不同水文测量值的表格,如下所示。
+----------------+----------------------+-------+--------------------+-------------+------------------+
| observation_id | observation_datetime | level | water_temperature |precipitation|precipitation_type|
+----------------+----------------------+-------+--------------------+-------------+------------------+
| 1 | 2019-03-11 11:00:00 | 11 | 21 | 31 |
| 2 | 2019-03-12 12:00:00 | 12 | 22 | 32 |
| 3 | 2019-03-13 13:00:00 | 13 | 23 | 33 |
| 4 | 2019-03-14 14:00:00 | 14 | 24 | 34 |我有这些描述度量的模型。
class AbstractMeasurement(model.Model):
observation_datetime = models.DateTimeField()
observation = models.ForeignKey(Observation, on_delete = models.DO_NOTHING)
class Meta:
abstract = True
class Level(AbstractMeasurement):
level = models.DecimalField()
class WaterTemperature(AbstractMeasurement):
air_temperature = models.DecimalField()
class Precipitation(AbstractMeasurement):
precipitation = models.DecimalField()
precipitation_type = models.CharField()等。
level主要的测量和测量离不开Level。Level是基本模型。
在mysql中,我可以通过下面的查询来完成
SELECT level.observation_id,
level.observation_datetime,
level.level,
water_temperature.water_temperature,
precipitation.precipitation,
precipitation.precipitation_type
FROM level
LEFT JOIN precipitation ON
level.observation_datetime = precipitation.observation_datetime
AND
level.observation_id = precipitation.observation_id
LEFT JOIN water_temperature ON
level.observation_datetime = water_temperature.observation_datetime
AND
level.observation_id = water_temperature.observation_id;如何在没有外键关系的模型中加入django?
发布于 2019-03-13 16:01:18
您可以实现您想要的结果,但这将是不必要的低效(甚至比您发布的SQL查询还要低)。由于您当前的模型结构已经相当扭曲,如果您可以更改模型,那么您应该这样做。
也就是说,下面是如何将Precipitation数据带入Level查询的方法。每个字段和行都需要一个子查询:
from django.db.models import Q, OuterRef, Subquery
join_criteria = Q(
observation_id=OuterRef('observation_id'),
observation_datetime = OuterRef('observation_datetime')
)
subquery_precipitation = Subquery(Precipitation.objects
.filter(join_criteria)
.values('precipitation')[:1])
subquery_precipitation_type = Subquery(Precipitation.objects
.filter(join_criteria)
.values('precipitation_type')[:1])
levels = (Level.objects
.annotate(precipitation=subquery_precipitation)
.annotate(precipitation_type=subquery_precipitation_type))现在,尝试将字段数乘以查询中的预期行数-这就是需要执行的子查询数。
因此,这是一个概念证明,您可以在小表和几个字段中使用。它不适合于大型数据集和许多字段。你真的应该重新考虑一下你的模型。
有了合适的模型,就可以很容易地实现你需要的东西。
https://stackoverflow.com/questions/55135563
复制相似问题