我用的是Django 1.9。我有一个Django表,按组织按月表示特定度量的值,其中包含原始值和百分比:
class MeasureValue(models.Model):
org = models.ForeignKey(Org, null=True, blank=True)
month = models.DateField()
calc_value = models.FloatField(null=True, blank=True)
percentile = models.FloatField(null=True, blank=True)
一般每月大约有10000人。我的问题是我是否可以加快设定模型值的过程。
目前,我通过使用Django过滤器查询检索一个月内的所有measurevalues来计算百分位数,将其转换为pandas数据帧,然后使用scipy的rankdata
来设置列组和百分位数。我这样做是因为pandas和rankdata
是有效的,能够忽略空值,并且能够以我想要的方式处理重复的值,所以我对这个方法很满意:
records = MeasureValue.objects.filter(month=month).values()
df = pd.DataFrame.from_records(records)
// use calc_value to set percentile on each row, using scipy's rankdata
但是,我需要从dataframe中检索每个百分点值,并将其设置回模型实例。现在,我通过遍历dataframe的行并更新每个实例来完成此操作:
for i, row in df.iterrows():
mv = MeasureValue.objects.get(org=row.org, month=month)
if (row.percentile is None) or np.isnan(row.percentile):
row.percentile = None
mv.percentile = row.percentile
mv.save()
这是毫不奇怪的相当缓慢。有没有什么有效的Django方法可以通过让一个数据库写而不是数万个数据库来加速呢?我有checked the documentation,但看不到。
原子事务可以减少在循环中花费的时间:
Django的默认行为是以自动提交模式运行。除非事务处于活动状态,否则每个查询都会立即提交到数据库。
通过使用
with transaction.atomic()
,所有插入都被分组到一个事务中。提交事务所需的时间在所附的所有insert语句中摊销,因此每个insert语句的时间大大减少。从Django 2.2开始,您可以使用^{} queryset方法有效地更新所提供模型实例上的给定字段,通常只需一个查询:
在旧版本的Django中,可以将^{} 与
Case
/When
一起使用,例如:相关问题 更多 >
编程相关推荐