diff --git a/openedx/core/djangoapps/content/course_overviews/models.py b/openedx/core/djangoapps/content/course_overviews/models.py index 2ac48e523b..27198452d0 100644 --- a/openedx/core/djangoapps/content/course_overviews/models.py +++ b/openedx/core/djangoapps/content/course_overviews/models.py @@ -40,6 +40,10 @@ from xmodule.tabs import CourseTab log = logging.getLogger(__name__) +class CourseOverviewCaseMismatchException(Exception): + pass + + @python_2_unicode_compatible class CourseOverview(TimeStampedModel): """ @@ -167,6 +171,11 @@ class CourseOverview(TimeStampedModel): if course_overview.exists(): log.info(u'Updating course overview for %s.', six.text_type(course.id)) course_overview = course_overview.first() + # MySQL ignores casing, but CourseKey doesn't. To prevent multiple + # courses with different cased keys from overriding each other, we'll + # check for equality here in python. + if course_overview.id != course.id: + raise CourseOverviewCaseMismatchException(course_overview.id, course.id) else: log.info(u'Creating course overview for %s.', six.text_type(course.id)) course_overview = cls() @@ -248,8 +257,8 @@ class CourseOverview(TimeStampedModel): with store.bulk_operations(course_id): course = store.get_course(course_id) if isinstance(course, CourseDescriptor): - course_overview = cls._create_or_update(course) try: + course_overview = cls._create_or_update(course) with transaction.atomic(): course_overview.save() # Remove and recreate all the course tabs