【发布时间】:2021-12-24 20:49:06
【问题描述】:
当前在我的项目中,我有一层这样的模型:
- 传感器类:存储不同的传感器
- Entry 类:每当发生新数据输入时存储
- 数据类:为每个条目存储数据对。
一般来说,使用该附加类是因为我对不同的传感器有不同的字段,并且我想将它们存储在一个数据库中,所以我是通过两种方法做到这一点的,一种用于获取数据的输入,另一种用于获取数据。传感器中的一个如下:
class Data(models.Model):
key = models.CharField(max_length=50)
value = models.CharField(max_length=50)
entry = models.ForeignKey(Entry, on_delete=CASCADE, related_name="dataFields")
def __str__(self):
return str(self.id) + "-" + self.key + ":" + self.value
class Entry(models.Model):
time = models.DateTimeField()
sensor = models.ForeignKey(Sensor, on_delete=CASCADE, related_name="entriesList")
def generateFields(self, field=None):
"""
Generate the fields by merging the Entry and data fields.
Outputs a dictionary which contains all fields.
"""
if field is None:
field_set = self.dataFields.all()
else:
field_set = self.dataFields.filter(key=field)
output = {"timestamp": self.time.timestamp()}
for key, value in field_set.values_list("key", "value"):
try:
floated = float(value)
isnan = math.isnan(floated)
except (TypeError, ValueError):
continue
if isnan:
return None
else:
output[key] = floated
return output
class Sensor(models.Model):
.
.
.
def generateData(self, fromTime, toTime, field=None):
fromTime = datetime.fromtimestamp(fromTime)
toTime = datetime.fromtimestamp(toTime)
entries = self.entriesList.filter(time__range=(toTime, fromTime)).order_by(
"time"
)
output = []
for entry in entries:
value = entry.generateFields(field)
if value is not None:
output.append(value)
return output
在尝试解决时间问题后(因为运行此查询约 5000-10000 个条目花费了太长时间,几乎 10 秒!),我发现大部分时间(大约 95%)都花在了方法上对于generateFields(),我一直在寻找缓存它的选项(通过使用cached_property),使用不同的方法,但到目前为止都没有真正奏效。
是否有一种方法可以在保存模型时自动将generateFields() 的结果存储在数据库中?或者可能只是保存反向查询self.dataFields.all() 的结果?我知道这是罪魁祸首,因为对于 5000 个条目,平均至少有 25000 个数据字段。
(感谢 Jacinator 的注释和改进)上面是 Jacinator 更改后的代码,但问题(和问题)仍然存在,因为缓存字段将加速该过程几乎 25-50 倍( !!)当我的实际数据集可能更大时(1~分钟运行查询不是真的可以接受),这很关键
【问题讨论】:
标签: python django django-models optimization django-queryset