Skip to content

Commit

Permalink
fix: bulk create on mysql
Browse files Browse the repository at this point in the history
  • Loading branch information
zacharis278 committed Aug 6, 2024
1 parent d7ee7be commit 19d9092
Show file tree
Hide file tree
Showing 3 changed files with 40 additions and 7 deletions.
7 changes: 1 addition & 6 deletions edx_exams/apps/api/v1/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -873,12 +873,7 @@ def post(self, request, course_id):
data={'detail': 'Exam does not exist'}
)

StudentAllowance.objects.bulk_create(
allowance_objects,
update_conflicts=True,
unique_fields=['user', 'exam'],
update_fields=['extra_time_mins']
)
StudentAllowance.bulk_create_or_update(allowance_objects)

return Response(status=status.HTTP_200_OK)
else:
Expand Down
22 changes: 21 additions & 1 deletion edx_exams/apps/core/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

from django.contrib.auth.models import AbstractUser
from django.core.exceptions import ObjectDoesNotExist
from django.db import models, transaction
from django.db import connection, models, transaction
from django.db.models import Q
from django.utils.translation import gettext_lazy as _
from model_utils.models import TimeStampedModel
Expand Down Expand Up @@ -454,6 +454,26 @@ class Meta:
verbose_name = 'student allowance'
unique_together = ('user', 'exam')

@classmethod
def bulk_create_or_update(cls, allowances):
"""
Create or update multiple allowances.
SQLite and Postgres have an additional requirement for bulk_create
when using update_conflicts=True. This app expects to run on MySQL
however our tests run on SQLite where 'unique_fields' is needed.
"""
unique_fields = None
if connection.features.supports_update_conflicts_with_target:
unique_fields = ['user', 'exam']

cls.objects.bulk_create(
allowances,
update_conflicts=True,
unique_fields=unique_fields,
update_fields=['extra_time_mins'],
)

@classmethod
def get_allowances_for_course(cls, course_id):
"""
Expand Down
18 changes: 18 additions & 0 deletions edx_exams/apps/core/tests/test_models.py
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,24 @@ def setUp(self):
self.course_id = 'course-v1:edX+Test+Test_Course'
self.exam = ExamFactory(course_id=self.course_id)

def test_bulk_create_or_update(self):
"""
Test bulk_create_or_update can create new allowances and update existing ones.
"""
conflict_user = UserFactory()
conflict_allowance = StudentAllowanceFactory(user=conflict_user, exam=self.exam, extra_time_mins=66)
allowances = [
StudentAllowance(user=conflict_user, exam=self.exam, extra_time_mins=19),
StudentAllowance(user=UserFactory(), exam=self.exam, extra_time_mins=29),
StudentAllowance(user=UserFactory(), exam=self.exam, extra_time_mins=39),
]

self.assertEqual(StudentAllowance.objects.count(), 1)
StudentAllowance.bulk_create_or_update(allowances)
self.assertEqual(StudentAllowance.objects.count(), 3)
conflict_allowance.refresh_from_db()
self.assertEqual(conflict_allowance.extra_time_mins, 19)

def test_get_allowance_for_user(self):
user = UserFactory()
user_2 = UserFactory()
Expand Down

0 comments on commit 19d9092

Please sign in to comment.