Оптимизация обработки файла CSV в запросе POST (Django Rest Framework) - PullRequest
0 голосов
/ 26 января 2020

У меня есть пост-запрос, который принимает файл CSV и сохраняет все действительные данные в этом файле в моделях БД. Но это невероятно медленно, потому что файлы CSV могут быть огромными. Есть ли лучший способ сделать это?

def post(self, request, *args, **kwargs):
    serializer = self.get_serializer(data=request.data)
    serializer.is_valid(raise_exception=True)
    file = serializer.validated_data['file']
    decoded_file = file.read().decode()
    io_string = io.StringIO(decoded_file)
    reader = csv.reader(io_string)

    for row in reader:
      if check_deal_validity(row):
        try:
          Client.objects.get(username=row[0])
        except ObjectDoesNotExist:
          client = Client(username=row[0])
          client.save()

        try:
          Item.objects.get(name=row[1])
        except ObjectDoesNotExist:
          item = Item(name=row[1])
          item.save()

        deal = Deal(
          client=Client.objects.get(username=row[0]),
          item=Item.objects.get(name=row[1]),
          total=row[2],
          quantity=row[3],
          date=row[4],
        )
        deal.save()
        Client.objects.filter(username=deal.client).update(spent_money=F('spent_money') + deal.total)
        if check_item_existence_for_client(
          client=deal.client,
          item=deal.item
        ):
          pass
        else:
          deal.client.gems.add(deal.item)

    return Response(status=status.HTTP_204_NO_CONTENT)

1 Ответ

0 голосов
/ 26 января 2020

Если это большой файл, а вы делаете большую вставку, то это нужно делать вне цикла запрос-ответ, который использует Django.

Я бы предложил интегрировать Для этого asyn c очередь задач с вашим проектом, так что посмотрите на Celery, redis-queue и huey.

Кроме того, вы делаете это очень неоптимизированным способом и можете использовать bulk_create внутри django ORM для уменьшения количества отдельных вставок в пользу массовой операции.

...