Bug #102150
AttributeError: booking has multiple checks
0%
Description
https://sentry.entrouvert.org/entrouvert/publik/issues/137994/
AttributeError: booking has multiple checks (8 additional frame(s) were not displayed) ... File "chrono/manager/views.py", line 3615, in get_context_data self.complete_event_attributes(self.agenda, event, context) File "chrono/manager/views.py", line 3601, in complete_event_attributes event.present_count = len([b for b in booked if b.user_check and b.user_check.presence]) File "chrono/manager/views.py", line 3601, in <listcomp> event.present_count = len([b for b in booked if b.user_check and b.user_check.presence]) File "django/utils/functional.py", line 57, in __get__ res = instance.__dict__[self.name] = self.func(instance) File "chrono/agendas/models.py", line 3470, in user_check raise AttributeError('booking has multiple checks')
Related issues
History
Updated by Robot Gitea about 2 months ago
- Status changed from Nouveau to En cours
Lauréline Guérin (lguerin) a ouvert une pull request sur Gitea concernant cette demande :
- URL : https://git.entrouvert.org/entrouvert/chrono/pulls/432
- Titre : WIP: manager: remove transaction around booking from subscription & audit (#102150)
- Modifications : https://git.entrouvert.org/entrouvert/chrono/pulls/432/files
Updated by Robot Gitea about 2 months ago
- Status changed from Solution proposée to Solution validée
Gael Pasgrimaud (gpasgrimaud) a approuvé une pull request sur Gitea concernant cette demande :
Updated by Benjamin Dauvergne about 2 months ago
- Status changed from Solution validée to En cours
Le patch ne corrige pas le problème, sans un index d'unicité ou une transaction avec un lock sur le kwargs de get_or_create() ce n'est pas possible1 de garantir l'atomicité et d'éviter un MultipleObjectsReturned. L'index d'unicité donne un verrou implicite entre appels à get_or_create().
Je ne sais pas si on souhaite une unicité globale sur (event, user_external_id)
. Si ce n'est pas le cas il faudrait un verrou dans une transaction sur event via select_for_update() (c'est pas le verrou le plus fin mais ça parait suffisant), ça ne protégera que cette section critique, si d'autres endroits crée des Booking sur cet Event il faudrait le même verrou.
with atomic(): list(Event.objects.filter(id=event.id).select_for_update()) cur.execute('SELECT pg_advisory_lock(%s)', [lock_id]) ...etc event.booking_set.get_or_create(user_external_id=user_external_id, ...)
1 voir le warning dans https://docs.djangoproject.com/en/5.1/ref/models/querysets/#get-or-create
Updated by Benjamin Dauvergne about 2 months ago
Autre solution un index unique partiel en ajoutant un champ booléen unique_by_user_external_id = BooleanField(default=False)
et un index partiel sur (event_id, user_external_id) WHERE unique_by_user_external_id
et ajouter unique_by_user_external_id=True
dans get_or_create().
Updated by Robot Gitea about 2 months ago
Lauréline Guérin (lguerin) a fermé une pull request sur Gitea concernant cette demande.
Updated by Lauréline Guérin about 2 months ago
- Status changed from En cours to Nouveau
- Assignee deleted (
Lauréline Guérin)
Updated by Valentin Deniaud about 2 months ago
- Has duplicate Bug #94909: agendas: ne pas planter s'il y a plusieurs pointages pour une réservation added
Updated by Valentin Deniaud about 2 months ago
- Related to Développement #80371: plages libres, permettre plusieurs pointages par réservation added