misc: optimize using raw sql

Use raw SQL to remove overhead of Django ORM.
This commit is contained in:
Benjamin Dauvergne 2023-04-13 23:32:21 +02:00
parent 81c5984edc
commit 58b91ba0de
1 changed files with 74 additions and 18 deletions

View File

@ -11,10 +11,19 @@ import urllib.parse
import zoneinfo
from django.conf import settings
from django.db import connection
from django.http import JsonResponse
from django.utils.text import slugify
from ants_hub.data.models import Config, Lieu, Plage, RendezVous, TypeDeRdv, make_available_time_slots
from ants_hub.data.models import (
Config,
HoraireList,
Lieu,
Plage,
RendezVous,
TypeDeRdv,
make_available_time_slots,
)
ANTS_TIMEZONE = zoneinfo.ZoneInfo('Europe/Paris')
@ -117,6 +126,9 @@ def available_time_slots_parse_qs(request):
return meeting_point_ids, start_date, end_date, reason, documents_number
USE_ORM = False
@authenticate
def available_time_slots(request):
try:
@ -138,28 +150,72 @@ def available_time_slots(request):
status=422,
)
types_de_rdv = [reason]
qs = Plage.objects.filter(lieu__id__in=meeting_point_ids)
qs = qs.filter(type_de_rdv__in=types_de_rdv)
qs = qs.filter(date__gte=start_date, date__lte=end_date)
qs = qs.filter(personnes=documents_number)
qs = qs.select_related('lieu', 'lieu__collectivite')
base_url = getattr(settings, 'BASE_URL', None)
if not base_url:
base_callback_url = request.build_absolute_uri('/')
if USE_ORM:
qs = Plage.objects.filter(lieu__id__in=meeting_point_ids)
qs = qs.filter(type_de_rdv__in=types_de_rdv)
qs = qs.filter(date__gte=start_date, date__lte=end_date)
qs = qs.filter(personnes=documents_number)
qs = qs.select_related('lieu', 'lieu__collectivite')
qs = qs.order_by('date').values_list(
'date',
'horaires',
'duree',
'lieu__pk',
'lieu__nom',
'lieu__collectivite__pk',
'lieu__collectivite__nom',
)
else:
with connection.cursor() as cur:
cur.execute(
'''\
SELECT plage.date, plage.horaires, plage.duree, lieu.id, lieu.nom, collectivite.id, collectivite.nom
FROM
ants_hub_plage AS plage,
ants_hub_lieu AS lieu,
ants_hub_collectivite AS collectivite
WHERE
plage.lieu_id = lieu.id
AND
lieu.collectivite_id = collectivite.id
AND
plage.type_de_rdv IN (%s)
AND
plage.date >= %%s
AND
plage.date <= %%s
AND
plage.personnes = %%s'''
% ','.join(['%s'] * len(types_de_rdv)),
[*types_de_rdv, start_date, end_date, documents_number],
)
def generator():
for (
date,
horaires,
duree,
lieu_pk,
lieu_nom,
collectivite_pk,
collectivite_nom,
) in cur.fetchall():
horaires = HoraireList.from_str(horaires)
yield date, horaires, duree, lieu_pk, lieu_nom, collectivite_pk, collectivite_nom
qs = list(generator())
slots_by_lieu = collections.defaultdict(list)
date_by_lieu = collections.defaultdict(set)
slot_count = 0
qs = qs.order_by('date').values_list(
'date',
'horaires',
'duree',
'lieu__pk',
'lieu__nom',
'lieu__collectivite__pk',
'lieu__collectivite__nom',
)
base_url = getattr(settings, 'BASE_URL', None)
if not base_url:
base_callback_url = request.build_absolute_uri('/')
for date, horaires, duree, lieu_pk, lieu_nom, collectivite_pk, collectivite_nom in qs:
lieu_slug = slugify(lieu_nom)
collectivite_slug = slugify(collectivite_nom)