У меня есть такая модель:
class Stock(models.Model):
product = models.ForeignKey(Product)
place = models.ForeignKey(Place)
date = models.DateField()
quantity = models.IntegerField()
Мне нужно получить самую последнюю версию (по date
) quantity
за каждые product
за каждые place
, с почти 500 продуктами,100 мест и 350000 складских записей в базе данных.
Мой текущий код такой, он работал на тестировании, но с реальными данными так долго, что бесполезен
stocks = Stock.objects.filter(product__in=self.products,
place__in=self.places, date__lt=date_at)
stock_values = {}
for prod in self.products:
for place in self.places:
key = u'%s%s' % (prod.id, place.id)
stock = stocks.filter(product=prod, place=place, date=date_at)
if len(stock) > 0:
stock_values[key] = stock[0].quantity
else:
try:
stock = stocks.filter(product=prod, place=place).order_by('-date')[0]
except IndexError:
stock_values[key] = 0
else:
stock_values[key] = stock.quantity
return stock_values
Как быВы делаете это быстрее?
Редактировать: Переписал код следующим образом:
stock_values = {}
for product in self.products:
for place in self.places:
try:
stock_value = Stock.objects.filter(product=product, place=place, date__lte=date_at)\
.order_by('-date').values('cant')[0]['cant']
except IndexError:
stock_value = 0
stock_values[u'%s%s' % (product.id, place.id)] = stock_value
return stock_values
Он работает лучше (от 256 секунд до 64), но все же нужно улучшить его,Может быть, какой-то пользовательский SQL, я не знаю ...