﻿id	summary	reporter	owner	description	type	status	component	version	severity	resolution	keywords	cc	stage	has_patch	needs_docs	needs_tests	needs_better_patch	easy	ui_ux
22073	Backwards migration on ManyToMany field does not remove intermediary table	Ben Davis	Andrew Godwin	"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:


{{{#!python
# 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."	Bug	closed	Migrations	dev	Release blocker	fixed		Ben Davis	Accepted	1	0	0	0	0	0
