Opened 10 years ago
Closed 10 years ago
#25904 closed Bug (duplicate)
--fake-initial does not work for ManyToMany with through Model
| Reported by: | Maciej Pawlisz | Owned by: | Tim Graham |
|---|---|---|---|
| Component: | Migrations | Version: | 1.9 |
| Severity: | Release blocker | Keywords: | |
| Cc: | Triage Stage: | Accepted | |
| Has patch: | no | Needs documentation: | no |
| Needs tests: | no | Patch needs improvement: | no |
| Easy pickings: | no | UI/UX: | no |
Description
I came across this issue when migrating from django 1.6.11 and south. When model has ManyToMany field then automatic initial migration contains AddField operation for this field, which of course is not present in database, so django thinks that it cannot fake this migration.
How to reproduce:
fake_through.models.py:
from django.db import models
class A(models.Model):
b = models.ManyToManyField('B', through="C")
class B(models.Model):
pass
class C(models.Model):
a = models.ForeignKey('A')
b = models.ForeignKey('B')
commands:
python manage.py makemigrations fake_through python manage.py migrate fake_through python manage.py migrate fake_through zero --fake python manage.py migrate fake_through --fake-initial django.db.utils.OperationalError: table "fake_through_a" already exists
Change History (5)
comment:1 by , 10 years ago
comment:2 by , 10 years ago
It was Django 1.9. From what I see when initial is True, django proceeds to checking db schema and this check fails. Actually it fails with every ManyToManyField, because it is added in AddField operation, but is not present in database schema:
djang.db.migrations.executor.py:291
db_field = model._meta.get_field(operation.name).column
fields = self.connection.introspection.get_table_description(self.connection.cursor(), table)
if db_field not in (f.name for f in fields):
return False, project_state
Easy fix would be adding this line before that check:
if isinstance(operation.field,models.ManyToMany):
continue
But maybe the bug is somewhere else ie. why model._meta.get_field(operation.name).column is not None for ManyToManyField ?
comment:3 by , 10 years ago
| Severity: | Normal → Release blocker |
|---|---|
| Triage Stage: | Unreviewed → Accepted |
Thanks, I understand now. I'll have to look at the code a bit more to advise on the proper fix. For reference, db97a8849519a3933bf4abd2184efd68ebc21965 added the Migration.initial option.
comment:4 by , 10 years ago
| Owner: | changed from to |
|---|---|
| Status: | new → assigned |
comment:5 by , 10 years ago
| Resolution: | → duplicate |
|---|---|
| Status: | assigned → closed |
The fix for #25904 should address this as whether or not the ManyToManyField uses an explicit through model doesn't matter.
Did you set the version on the ticket correctly? I might expect that behavior in Django 1.8 but if you generated the migrations with Django 1.9, then they should have the initial attribute set such that this shouldn't happen.