Django:在 Python 与 SQL 中过滤和操作对象

Django: Filtering and Manipulating Objects in Python vs SQL

我有一个看起来像这样的模型:

class MyModel(models.Model):
    name = models.CharField(max_length=255)
    date = models.DateField()
    units = models.PositiveIntegerField(default=0)
    cost = models.DecimalField(max_digits=12, decimal_places=4, default=0)
    ...

我需要按日期(即按周、月等)对所有对象进行分组。对于每个组,我需要对总单位和成本求和并执行一些其他杂项操作。

我可以通过大量访问数据库来完成大部分工作。例如,如果 periods 是一个元组列表,其开始和结束值为 datetime.dates,我可以这样做:

for period in periods:
    mymodels = MyModel.objects.filter(date__gte=period[0], date__lte=period[1])
    sums = mymodels.aggregate(Sum('units'), Sum('cost'))
    # do other stuff

或者我可以一次获得所有模型,然后在 python 中完成其余的工作,例如:

models = MyModel.objects.all()
for period in periods:
    period_models = [x for x in models if x.date >= period[0] and x.date <= period]
    period_units = sum(x.units for x in period_models)
    period_cost = sum(x.cost for x in period_models)
    # do other stuff

哪种方法更好,或者有第三种选择吗?当我处理 50k 个对象时,我担心速度。

使用第一种方法,我在每个周期访问数据库两次(一次获取相关模型,一次求和值),这看起来很笨拙。使用后一种方法,我只访问数据库一次,但我正在将一堆东西加载到内存中(但另一方面,内存很便宜)。

我会说让数据库来处理。它可能不会在较小的集合上产生明显的差异,但数据库会更有效地处理任何显着大小的集合。他们通常会更好地利用多核,并针对此类数字运算进行了大量优化。

我进行了快速搜索并得出了这篇文章。

http://patshaughnessy.net/2015/6/18/dont-let-your-data-out-of-the-database

基本上让您的数据库处理尽可能多的处理,并且只获取您的结果并进行您可能需要的任何收尾工作。即使你打了两次,它也会更好地扩展。