Opened 13 months ago

Closed 12 months ago

Last modified 12 months ago

#22073 closed Bug (fixed)

Backwards migration on ManyToMany field does not remove intermediary table

Reported by: bendavis78 Owned by: andrewgodwin
Component: Migrations Version: master
Severity: Release blocker Keywords:
Cc: bendavis78 Triage Stage: Accepted
Has patch: yes Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description

When a migration is performed where a ManyToMany field is added, the intermediary table is automatically created. However, when performing a backwards migration, this table is not deleted. Consider the following:

# locations/models.py

from products.models import Product

class Location(models.Model):
    name = models.CharField(max_length=100)
    products_sold = models.ManyToManyField(Product)

We create our initial migration for locations and run it:

$ ./manage.py makemigrations locations
Migrations for 'locations':
  0001_initial.py:
      - Create model Location

$ ./manage.py migrate locations
Operations to perform:
  Apply all migrations: locations
Running migrations:
  Applying locations.0001_initial... OK

Now, if we want to, we should be able to undo that migration and re-apply it. Often in development I re-do my initial migrations to keep things simple before I do my first deployment. Unfortunately when you re-aplly the migration we get an exception, because the backward migration didn't remove the intermediary table:

$ ./manage.py migrate locations zero
Operations to perform:
  Unapply all migrations: locations
Running migrations:
  Unapplying locations.0001_initial... OK

$ ./manage.py migrate locations
Operations to perform:
  Apply all migrations: locations
Running migrations:
  Applying locations.0001_initial...Traceback (most recent call last):
  File "./manage.py", line 10, in <module>
    execute_from_command_line(sys.argv)
  File "/tmp/djangotest/src/django/django/core/management/__init__.py", line 427, in execute_from_command_line
    utility.execute()
  ...
  File "/tmp/djangotest/src/django/django/db/backends/utils.py", line 77, in execute
    return super(CursorDebugWrapper, self).execute(sql, params)
  File "/tmp/djangotest/src/django/django/db/backends/utils.py", line 61, in execute
    return self.cursor.execute(sql, params)
  File "/tmp/djangotest/src/django/django/db/utils.py", line 93, in __exit__
    six.reraise(dj_exc_type, dj_exc_value, traceback)
  File "/tmp/djangotest/src/django/django/db/backends/utils.py", line 61, in execute
    return self.cursor.execute(sql, params)
django.db.utils.ProgrammingError: relation "locations_location_products_sold" already exists

I've attached an example project where this can be reproduced.

Attachments (1)

myproject.tar.gz (2.4 KB) - added by bendavis78 13 months ago.
example project

Download all attachments as: .zip

Change History (9)

Changed 13 months ago by bendavis78

example project

comment:1 Changed 13 months ago by bendavis78

  • Cc bendavis78 added
  • Needs documentation unset
  • Needs tests unset
  • Patch needs improvement unset

comment:2 Changed 13 months ago by bendavis78

  • Needs tests set

comment:3 Changed 13 months ago by bendavis78

  • Has patch set
  • Needs tests unset

I've created a pull request with a fix and a new test for the creation of models with M2M fields: https://github.com/django/django/pull/2315

comment:4 Changed 13 months ago by timo

  • Triage Stage changed from Unreviewed to Ready for checkin

comment:5 Changed 13 months ago by MarkusH

  • Triage Stage changed from Ready for checkin to Accepted

comment:6 Changed 12 months ago by andrewgodwin

  • Owner set to andrewgodwin
  • Status changed from new to assigned

comment:7 Changed 12 months ago by Ben Davis <bendavis78@…>

  • Resolution set to fixed
  • Status changed from assigned to closed

In df2652c44836374bb8a691e755edbc153805f9cc:

Fixed #22073 - Ensure CreateTable operation handles backwards migration correctly when M2M fields are present

comment:8 Changed 12 months ago by Andrew Godwin <andrew@…>

In cdf6eba1816669bd77a28da903d931b5a4b15992:

Merge pull request #2315 from bendavis78/issues/22073

Fixed #22073 - Ensure CreateTable operation handles backwards migration correctly when M2M fields are present

Note: See TracTickets for help on using tickets.
Back to Top