From 52ca02fdc4a7cdf14fc523428922d45a210181b8 Mon Sep 17 00:00:00 2001 From: Ned Batchelder Date: Tue, 14 Feb 2017 12:48:33 -0500 Subject: [PATCH 1/4] model_name can be non-None, and model is still None --- openedx/core/lib/django_courseware_routers.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openedx/core/lib/django_courseware_routers.py b/openedx/core/lib/django_courseware_routers.py index ea3a290725..5d6ecec3de 100644 --- a/openedx/core/lib/django_courseware_routers.py +++ b/openedx/core/lib/django_courseware_routers.py @@ -51,7 +51,7 @@ class StudentModuleHistoryExtendedRouter(object): """ if model_name is not None: model = hints.get('model') - if self._is_csmh(model): + if model is not None and self._is_csmh(model): return db == self.DATABASE_NAME if db == self.DATABASE_NAME: return False From 169414b734d4f2318786ae171ef1860316c888ce Mon Sep 17 00:00:00 2001 From: Ned Batchelder Date: Tue, 14 Feb 2017 12:35:37 -0500 Subject: [PATCH 2/4] An idempotent migration to add an email uniqueness constraint --- .../migrations/0011_auto_20170214_1200.py | 35 +++++++++++++++++++ 1 file changed, 35 insertions(+) create mode 100644 common/djangoapps/student/migrations/0011_auto_20170214_1200.py diff --git a/common/djangoapps/student/migrations/0011_auto_20170214_1200.py b/common/djangoapps/student/migrations/0011_auto_20170214_1200.py new file mode 100644 index 0000000000..726039d72d --- /dev/null +++ b/common/djangoapps/student/migrations/0011_auto_20170214_1200.py @@ -0,0 +1,35 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals + +from django.db import migrations + +# We used to have a uniqueness constraint on auth_user.email: +# https://github.com/edx/edx-platform/commit/c52727b0e0fb241d8211900975d3b69fe5a1bd57 +# +# That constraint was lost in the upgrade from Django 1.4->1.8. This migration +# adds it back. But because it might already exist in databases created +# long-enough ago, we have to do it idempotently. So we check for the +# existence of the constraint before creating it. + +def add_email_uniqueness_constraint(apps, schema_editor): + # Do we already have an email uniqueness constraint? + cursor = schema_editor.connection.cursor() + constraints = schema_editor.connection.introspection.get_constraints(cursor, "auth_user") + email_constraint = constraints.get("email", {}) + if email_constraint.get("columns") == ["email"] and email_constraint.get("unique") == True: + # We already have the constraint, we're done. + return + + # We don't have the constraint, make it. + schema_editor.execute("create unique index email on auth_user (email)") + + +class Migration(migrations.Migration): + + dependencies = [ + ('student', '0010_auto_20170207_0458'), + ] + + operations = [ + migrations.RunPython(add_email_uniqueness_constraint) + ] From 04557bbff362ae3b89e7dd98a1fb11e0aaeba50e Mon Sep 17 00:00:00 2001 From: Ned Batchelder Date: Tue, 14 Feb 2017 15:01:07 -0500 Subject: [PATCH 3/4] Make this no-op migration be a true no-op. --- .../student/migrations/0010_auto_20170207_0458.py | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/common/djangoapps/student/migrations/0010_auto_20170207_0458.py b/common/djangoapps/student/migrations/0010_auto_20170207_0458.py index e700f1ec66..901e70ebf3 100644 --- a/common/djangoapps/student/migrations/0010_auto_20170207_0458.py +++ b/common/djangoapps/student/migrations/0010_auto_20170207_0458.py @@ -26,9 +26,5 @@ class Migration(migrations.Migration): # ) operations = [ - migrations.RunSQL( - # Do nothing: - "select 1", - "select 1" - ) + # Nothing to do. ] From 98b250b66ed53fd4f52a85f1e8e897652b2d29f8 Mon Sep 17 00:00:00 2001 From: Ned Batchelder Date: Wed, 15 Feb 2017 11:16:07 -0500 Subject: [PATCH 4/4] A new django app for unicorn migrations --- cms/envs/common.py | 3 +++ common/djangoapps/database_fixups/__init__.py | 3 +++ .../migrations/0001_initial.py} | 3 +-- common/djangoapps/database_fixups/migrations/__init__.py | 0 lms/envs/common.py | 3 +++ 5 files changed, 10 insertions(+), 2 deletions(-) create mode 100644 common/djangoapps/database_fixups/__init__.py rename common/djangoapps/{student/migrations/0011_auto_20170214_1200.py => database_fixups/migrations/0001_initial.py} (93%) create mode 100644 common/djangoapps/database_fixups/migrations/__init__.py diff --git a/cms/envs/common.py b/cms/envs/common.py index 94145d2568..8daa48195f 100644 --- a/cms/envs/common.py +++ b/cms/envs/common.py @@ -959,6 +959,9 @@ INSTALLED_APPS = ( # management of user-triggered async tasks (course import/export, etc.) 'user_tasks', + + # Unusual migrations + 'database_fixups', ) diff --git a/common/djangoapps/database_fixups/__init__.py b/common/djangoapps/database_fixups/__init__.py new file mode 100644 index 0000000000..bea2d2681a --- /dev/null +++ b/common/djangoapps/database_fixups/__init__.py @@ -0,0 +1,3 @@ +""" +This app exists solely to host unusual database migrations. +""" diff --git a/common/djangoapps/student/migrations/0011_auto_20170214_1200.py b/common/djangoapps/database_fixups/migrations/0001_initial.py similarity index 93% rename from common/djangoapps/student/migrations/0011_auto_20170214_1200.py rename to common/djangoapps/database_fixups/migrations/0001_initial.py index 726039d72d..110104fdea 100644 --- a/common/djangoapps/student/migrations/0011_auto_20170214_1200.py +++ b/common/djangoapps/database_fixups/migrations/0001_initial.py @@ -1,7 +1,7 @@ # -*- coding: utf-8 -*- from __future__ import unicode_literals -from django.db import migrations +from django.db import migrations, models # We used to have a uniqueness constraint on auth_user.email: # https://github.com/edx/edx-platform/commit/c52727b0e0fb241d8211900975d3b69fe5a1bd57 @@ -27,7 +27,6 @@ def add_email_uniqueness_constraint(apps, schema_editor): class Migration(migrations.Migration): dependencies = [ - ('student', '0010_auto_20170207_0458'), ] operations = [ diff --git a/common/djangoapps/database_fixups/migrations/__init__.py b/common/djangoapps/database_fixups/migrations/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/lms/envs/common.py b/lms/envs/common.py index 54857fbc33..832bb30d62 100644 --- a/lms/envs/common.py +++ b/lms/envs/common.py @@ -2164,6 +2164,9 @@ INSTALLED_APPS = ( # Ability to detect and special-case crawler behavior 'openedx.core.djangoapps.crawlers', + + # Unusual migrations + 'database_fixups', ) # Migrations which are not in the standard module "migrations"