Django эффективно возвращает большой набор запросов в качестве ответа
У меня есть модель в django под названием "Sample". Я хочу запросить и вернуть большое количество строк ~ 100k на основе фильтров. Однако, возврат ответа занимает до 4-5 секунд, и я хотел бы узнать, могу ли я сделать это быстрее.
(Нужно улучшить конвертацию из queryset в df в response json. Не запрашивать из БД)
Мой текущий код выглядит следующим образом:
@api_view(['POST'])
def retrieve_signal_asset_weight_ts_by_signal(request):
#code to get item.id here based on request
qs = Sample.objects.filter(
data_date__range=[start_date, end_date],
item__id = item.id).values(*columns_required)
df = pd.DataFrame(list(qs), columns=columns_required)
response = df .to_json(orient='records')
return Response(response, status=status.HTTP_200_OK)
На основе нескольких тестовых примеров я заметил, что медленной частью является не получение данных из DB, а преобразование их в DataFrame и последующее возвращение в виде JSON.
Только на эту часть уходит около 2 секунд df = pd.DataFrame(list(qs), columns=columns_required)
. Я ищу более быстрый способ преобразования queryset в json, который я могу отправить как часть моего объекта "response"!
На основе этой ссылки я пробовал другие методы, включая django-pandas
и использование .values_list()
, но они кажутся медленнее, чем этот, и я заметил, что многие ответы довольно старые, поэтому мне интересно, есть ли в Django 3 что-нибудь, чтобы сделать это быстрее.
Спасибо
Версия Django: 3.2.6
С вашим кодом вы не можете написать:
(Нужно улучшить конвертацию из queryset в df в response json. Не запрашивать из БД)
.На самом деле на эту часть уходит около 2 секунд
.df = pd.DataFrame(list(qs), columns=columns_required)
Получение данных из базы данных - это ленивая операция, поэтому запрос будет выполняться только тогда, когда данные необходимы list(qs)
. Согласно документации:
QuerySets ленивы - акт создания QuerySet не включает в себя никакой активности базы данных. Вы можете складывать фильтры вместе хоть целый день, и Django не будет выполнять запрос до тех пор, пока QuerySet не будет оценен. Взгляните на этот пример:
Попытайтесь разделить операцию:
records = list(qs)
df = pd.DataFrame(records, columns=columns_required))
Теперь вы можете определить, какая операция отнимает много времени.
Можно посмотреть на StreamingHttpResponse