tests, test_recurring_events_api_fillslots_multiple_agendas_queries est très long (#77590) #86

Merged
lguerin merged 4 commits from wip/77590-test-perfs into main 2023-05-30 10:08:42 +02:00
4 changed files with 47 additions and 8 deletions

View File

@ -0,0 +1,21 @@
import django.db.models.expressions
import django.db.models.functions.datetime
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('agendas', '0152_auto_20230331_0834'),
]
operations = [
migrations.AddIndex(
model_name='event',
index=models.Index(
django.db.models.functions.datetime.ExtractWeekDay('start_datetime'),
django.db.models.expressions.F('start_datetime'),
condition=models.Q(('cancelled', False)),
name='start_datetime_dow_index',
),
),
]

View File

@ -1536,6 +1536,14 @@ class Event(models.Model):
class Meta:
ordering = ['agenda', 'start_datetime', 'duration', 'label']
unique_together = ('agenda', 'slug')
indexes = [
models.Index(
ExtractWeekDay('start_datetime'),
'start_datetime',
name='start_datetime_dow_index',
condition=models.Q(cancelled=False),
)
]
def __str__(self):
if self.label:

View File

@ -1853,14 +1853,15 @@ class RecurringFillslots(APIView):
Booking.objects.filter(primary_booking__in=bookings_to_cancel).update(
cancellation_datetime=cancellation_datetime
)
cancelled_events = [
get_short_event_detail(
request,
events_by_id[x.event_id],
multiple_agendas=True,
)
for x in bookings_to_cancel
]
if payload.get('include_booked_events_detail'):
cancelled_events = [
get_short_event_detail(
request,
events_by_id[x.event_id],
multiple_agendas=True,
)
for x in bookings_to_cancel
]
cancelled_count = bookings_to_cancel.update(cancellation_datetime=cancellation_datetime)
# and delete outdated cancelled bookings
Booking.objects.filter(
@ -1888,9 +1889,13 @@ class RecurringFillslots(APIView):
):
event_filter = Q()
agendas_by_slug = {a.slug: a for a in agendas}
agenda_slugs = set()
event_slugs = set()
for agenda_slug, days_by_event in slots.items():
agenda = agendas_by_slug[agenda_slug]
agenda_slugs.add(agenda_slug)
for event_slug, days in days_by_event.items():
event_slugs.add(event_slug)
lookups = {
'agenda__slug': agenda_slug,
'primary_event__slug': event_slug,
@ -1911,6 +1916,8 @@ class RecurringFillslots(APIView):
event_filter |= Q(**lookups)
events = Event.objects.filter(event_filter) if event_filter else Event.objects.none()
if agenda_slugs:
events = events.filter(agenda__slug__in=agenda_slugs, primary_event__slug__in=event_slugs)
events = events.filter(start_datetime__gte=start_datetime, cancelled=False)
if end_datetime:
events = events.filter(start_datetime__lte=end_datetime)

View File

@ -1294,6 +1294,9 @@ def test_recurring_events_api_fillslots_multiple_agendas_queries(app, user):
start_datetime=start, places=2, recurrence_end_date=end, recurrence_days=[1, 2], agenda=agenda
)
event.create_all_recurrences()
with connection.cursor() as cursor:
# force an analyze pass after we load data so PG has usable statistics
cursor.execute("ANALYZE;")
agenda_slugs = ','.join(str(i) for i in range(20))
resp = app.get('/api/agendas/recurring-events/?action=update&agendas=%s' % agenda_slugs)