#30381: django/contrib/auth/migrations/0011_update_proxy_permissions.py can 
cause a
unique constraint violation
----------------------------------------+------------------------
               Reporter:  Jon Dufresne  |          Owner:  nobody
                   Type:  Bug           |         Status:  new
              Component:  contrib.auth  |        Version:  2.2
               Severity:  Normal        |       Keywords:
           Triage Stage:  Unreviewed    |      Has patch:  0
    Needs documentation:  0             |    Needs tests:  0
Patch needs improvement:  0             |  Easy pickings:  0
                  UI/UX:  0             |
----------------------------------------+------------------------
 Use an existing database that was migrated using Django 2.1. This must
 contain auth permissions for proxy models. Per Django 2.1,
 `Permission.content_type` points to the concrete model's content type, not
 the proxy's.

 Once this database exists, steps to reproduce:

 1. Run a subset of migrations that includes the proxy model's app but does
 not include `0011_update_proxy_permissions`.
 2. This triggers the auth `create_permissions()` post migrate handler.
 3. `create_permissions()` generates new permissions for the proxy models
 that point to the proxy content type. The old ones that point to the
 concrete model still exist.
 4. Now run all migrations.
 5. `auth.0011_update_proxy_permissions` runs and tries to update the pre-
 existing proxy models. But as the auth permissions were already created
 during the previous migration run, this crashes with a unique constraint
 violation.

 Traceback (PostgreSQL backend):

 {{{
 Traceback (most recent call last):
   ...
   File ".../venv/lib64/python3.7/site-
 packages/django/core/management/commands/migrate.py", line 234, in handle
     fake_initial=fake_initial,
   File ".../venv/lib64/python3.7/site-
 packages/django/db/migrations/executor.py", line 117, in migrate
     state = self._migrate_all_forwards(state, plan, full_plan, fake=fake,
 fake_initial=fake_initial)
   File ".../venv/lib64/python3.7/site-
 packages/django/db/migrations/executor.py", line 147, in
 _migrate_all_forwards
     state = self.apply_migration(state, migration, fake=fake,
 fake_initial=fake_initial)
   File ".../venv/lib64/python3.7/site-
 packages/django/db/migrations/executor.py", line 245, in apply_migration
     state = migration.apply(state, schema_editor)
   File ".../venv/lib64/python3.7/site-
 packages/django/db/migrations/migration.py", line 124, in apply
     operation.database_forwards(self.app_label, schema_editor, old_state,
 project_state)
   File ".../venv/lib64/python3.7/site-
 packages/django/db/migrations/operations/special.py", line 190, in
 database_forwards
     self.code(from_state.apps, schema_editor)
   File ".../venv/lib64/python3.7/site-
 packages/django/contrib/auth/migrations/0011_update_proxy_permissions.py",
 line 30, in update_proxy_model_permissions
     ).update(content_type=new_content_type)
   File ".../venv/lib64/python3.7/site-packages/django/db/models/query.py",
 line 741, in update
     rows = query.get_compiler(self.db).execute_sql(CURSOR)
   File ".../venv/lib64/python3.7/site-
 packages/django/db/models/sql/compiler.py", line 1426, in execute_sql
     cursor = super().execute_sql(result_type)
   File ".../venv/lib64/python3.7/site-
 packages/django/db/models/sql/compiler.py", line 1097, in execute_sql
     cursor.execute(sql, params)
   File ".../venv/lib64/python3.7/site-
 packages/django/db/backends/utils.py", line 99, in execute
     return super().execute(sql, params)
   File ".../venv/lib64/python3.7/site-
 packages/django/db/backends/utils.py", line 67, in execute
     return self._execute_with_wrappers(sql, params, many=False,
 executor=self._execute)
   File ".../venv/lib64/python3.7/site-
 packages/django/db/backends/utils.py", line 76, in _execute_with_wrappers
     return executor(sql, params, many, context)
   File ".../venv/lib64/python3.7/site-
 packages/django/db/backends/utils.py", line 84, in _execute
     return self.cursor.execute(sql, params)
   File ".../venv/lib64/python3.7/site-packages/django/db/utils.py", line
 89, in __exit__
     raise dj_exc_value.with_traceback(traceback) from exc_value
   File ".../venv/lib64/python3.7/site-
 packages/django/db/backends/utils.py", line 84, in _execute
     return self.cursor.execute(sql, params)
 django.db.utils.IntegrityError: duplicate key value violates unique
 constraint "auth_permission_content_type_id_01ab375a_uniq"
 DETAIL:  Key (content_type_id, codename)=(168, add_myproxymodel) already
 exists.
 }}}

-- 
Ticket URL: <https://code.djangoproject.com/ticket/30381>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.

-- 
You received this message because you are subscribed to the Google Groups 
"Django updates" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to django-updates+unsubscr...@googlegroups.com.
To post to this group, send email to django-updates@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-updates/052.1bafa040574d456e69ba776946883af4%40djangoproject.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to