#30351 closed Bug (fixed)
Migration auth.0011_update_proxy_permissions fails for models recreated as a proxy.
Reported by: | Julien Enselme | Owned by: | Carlton Gibson |
---|---|---|---|
Component: | contrib.auth | Version: | 2.2 |
Severity: | Release blocker | Keywords: | |
Cc: | Simon Charette, Arthur Rio, Antoine Catton | Triage Stage: | Accepted |
Has patch: | no | Needs documentation: | no |
Needs tests: | no | Patch needs improvement: | no |
Easy pickings: | no | UI/UX: | no |
Description (last modified by )
I am trying to update my project to Django 2.2. When I launch python manage.py migrate
, I get this error message when migration auth.0011_update_proxy_permissions
is applying (full stacktrace is available here):
django.db.utils.IntegrityError: duplicate key value violates unique constraint "idx_18141_auth_permission_content_type_id_01ab375a_uniq" DETAIL: Key (co.ntent_type_id, codename)=(12, add_agency) already exists
.
It looks like the migration is trying to re-create already existing entries in the auth_permission
table. At first I though it cloud because we recently renamed a model. But after digging and deleting the entries associated with the renamed model from our database in the auth_permission
table, the problem still occurs with other proxy models.
I tried to update directly from 2.0.13 and 2.1.8. The issues appeared each time. I also deleted my venv and recreated it without an effect.
I searched for a ticket about this on the bug tracker but found nothing. I also posted this on django-users and was asked to report this here.
Change History (14)
comment:1 by , 6 years ago
Component: | Uncategorized → contrib.auth |
---|---|
Type: | Uncategorized → Bug |
comment:2 by , 6 years ago
Same problem for me.
If a Permission
exists already with the new content_type
and permission name
, IntegrityError
is raised since it violates the unique_key constraint on permission model i.e. content_type_id_code_name
comment:3 by , 6 years ago
To get into the situation where you already have permissions with the content type you should be able to do the following:
- Start on Django <2.2
- Create a model called 'TestModel'
- Migrate
- Delete the model called 'TestModel'
- Add a new proxy model called 'TestModel'
- Migrate
- Update to Django >=2.2
- Migrate
We think this is what happened in our case where we found this issue (https://sentry.thalia.nu/share/issue/68be0f8c32764dec97855b3cbb3d8b55/).
We have a proxy model with the same name that a previous non-proxy model once had. This changed during a refactor and the permissions + content type for the original model still exist.
Our solution will probably be removing the existing permissions from the table, but that's really only a workaround.
comment:4 by , 6 years ago
Cc: | added |
---|---|
Severity: | Normal → Release blocker |
Triage Stage: | Unreviewed → Accepted |
Reproduced with steps from comment. It's probably regression in 181fb60159e54d442d3610f4afba6f066a6dac05.
comment:5 by , 6 years ago
Description: | modified (diff) |
---|---|
Summary: | Migration auth.0011_update_proxy_permissions from Django 2.2 fails to apply → Migration auth.0011_update_proxy_permissions fails for models recreated as a proxy. |
comment:6 by , 6 years ago
Owner: | changed from | to
---|---|
Status: | new → assigned |
We do not automatically delete stale content types on purpose to avoid data loss. When deleting a model, the remove_stale_contenttypes.py
management command https://github.com/django/django/blob/master/django/contrib/contenttypes/management/commands/remove_stale_contenttypes.py should be ran. We can do two things here:
- Handle the
IntegrityError
with a helpful message to point to the command - Re-use existing content types
I think 1. is safer but I am open to suggestions.
comment:7 by , 6 years ago
It's also possible to get this kind of integrity error on the auth.0011 migration if another app is migrated first causing the auth post_migrations hook to run. The auth post migrations hook runs django.contrib.auth.management.create_permissions
, which writes the new form of the auth_permission records to the table. Then when the auth.0011 migration runs it tries to update things to the values that were just written.
To reproduce this behavior:
- pip install Django==2.1.7
- Create an app, let's call it
app
, with two models,TestModel(models.Model)
andProxyModel(TestModel)
the second one with proxy=True python manage.py makemigrations
python manage.py migrate
- pip install Django==2.2
- Add another model to
app
python manage.py makemigrations
- migrate the app only,
python manage.py migrate app
. This does not run the auth migrations, but does run the auth post_migrations hook - Note that new records have been added to auth_permission
python manage.py migrate
, this causes an integrity error when the auth.0011 migration tries to update records that are the same as the ones already added in step 8.
This has the same exception as this bug report, I don't know if it's considered a different bug, or the same one.
comment:8 by , 6 years ago
Yes it is the same issue. My recommendation to let the users figure it out with a helpful message still stands even if it may sound a bit painful, because:
- It prevents data loss (we don't do an automatic delete/create of permissions)
- It prevents security oversights (we don't re-use an existing permission)
- It shouldn't happen for most use cases
Again, I would love to hear some feedback or other alternatives.
comment:9 by , 6 years ago
Owner: | removed |
---|---|
Status: | assigned → new |
I won’t have time to work on this for the next 2 weeks so I’m de-assigning myself. I’ll pick it up again if nobody does and I’m available to discuss feedback/suggestions.
comment:10 by , 6 years ago
Owner: | set to |
---|---|
Status: | new → assigned |
comment:11 by , 6 years ago
I'll make a patch for this.
I'll see about raising a suitable warning from the migration but we already warn in the release notes for this to audit permissions: my initial thought was that re-using the permission would be OK. (I see Arthur's comment. Other thoughts?)
comment:12 by , 6 years ago
Being my first contribution I wanted to be super (super) careful with security concerns, but given the existing warning in the release notes for auditing prior to update, I agree that re-using the permission feels pretty safe and would remove overhead for people running into this scenario.
Thanks for taking this on Carlton, I'd be happy to review.
Please provide a sample project or enough details to reproduce the issue.