Opened 4 years ago

Closed 4 years ago

Last modified 4 years ago

#22293 closed Bug (fixed)

ERROR: relation "app_taggedcountryoforigin" already exists

Reported by: Daniel Hahler Owned by: nobody
Component: Migrations Version: master
Severity: Normal Keywords:
Cc: Triage Stage: Accepted
Has patch: yes Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no


There is a problem in db.backends.schema.alter_field, with the call to _alter_many_to_many:

it might try to rename a DB table to the same name.

With django-taggit, changing arguments for the TaggableManager a migration is created, which triggers a RENAME of a DB table, although the name is not changed (e.g. when changing blank).

The migration:

operations = [


field=taggit.managers.TaggableManager(through=app.models.TaggedCountryOfOrigin, blank=True, help_text=u'A comma-separated list of tags.', verbose_name=u'Country of origin'),


The SQL:

    % sqlmigrate app 0010
    ALTER TABLE "app_taggedcountryoforigin" RENAME TO "app_taggedcountryoforigin";
    ALTER TABLE "app_taggedcountryoforigin" DROP CONSTRAINT app__tag_id_5f04ec758472f8f8_fk_app_countryoforigintag_id;
    ALTER TABLE "app_taggedcountryoforigin" ADD CONSTRAINT app_taggedcountryoforigin_tag_id_5f04ec758472f8f8_fk FOREIGN KEY ("tag_id") REFERENCES "app_countryoforigintag" ("id") DEFERRABLE INITIALLY DEFERRED;

The SQL error: ERROR: relation "app_taggedcountryoforigin" already exists

The code path is as follows:

ipdb> l

128 elif isinstance(, six.string_types):
129 =

--> 130 schema_editor.alter_field(from_model, from_field, to_field)

132 def database_backwards(self, app_label, schema_editor, from_state, to_state):
133 self.database_forwards(app_label, schema_editor, from_state, to_state)
135 def describe(self):
136 return "Alter field %s on %s" % (, self.model_name)
138 def eq(self, other):

ipdb> from_model
<class 'fake.Model'>
ipdb> from_field
<taggit.managers.TaggableManager: country_of_origin>
ipdb> to_field
<taggit.managers.TaggableManager: country_of_origin>


766 # Rename the through table

--> 767 self.alter_db_table(old_field.rel.through, old_field.rel.through._meta.db_table, new_field.rel.through._meta.db_table)

768 # Repoint the FK to the other side

The code that calls it (from database_forwards):

if router.allow_migrate(schema_editor.connection.alias, to_model):

from_field = from_model._meta.get_field_by_name([0]
to_field = to_model._meta.get_field_by_name([0]
# If the field is a relatedfield with an unresolved, just
# set it equal to the other field side. Bandaid fix for AlterField
# migrations that are part of a RenameModel change.
if from_field.rel and

if isinstance(, six.string_types): =

elif isinstance(, six.string_types): =

schema_editor.alter_field(from_model, from_field, to_field)

(This gets triggered by my patch to taggit (, where I setup auto_created.

I came up with this in an attempt to fix another taggit issue with Django 1.7 ( - "changed through model: ValueError: Cannot alter field ... - they are not compatible types".)

I will provide a fix for this, but did not manage to come with a test case (for the test suite).

I would really appreciate it, if

Change History (4)

comment:1 Changed 4 years ago by Daniel Hahler

Sorry for the layout mess (please feel free to fix/edit it).

Here is a proposed fix for it:

comment:2 Changed 4 years ago by Aymeric Augustin

Triage Stage: UnreviewedAccepted

taggit is known to abuse the internals, but this looks like something Django should prevent.

comment:3 Changed 4 years ago by Tim Graham <timograham@…>

Resolution: fixed
Status: newclosed

In 1edfa155e34dde549ef0e93414f2846dce59e5f7:

Fixed #22293 -- Avoided renaming many-to-many tables to themselves.

Fixed this for both implementations of _alter_many_to_many, instead of
in alter_db_table itself (more implementations).

comment:4 Changed 4 years ago by Tim Graham <timograham@…>

In 21eaad68e6f26b9f88437c63d584c0a9fb39c9be:

[1.7.x] Fixed #22293 -- Avoided renaming many-to-many tables to themselves.

Fixed this for both implementations of _alter_many_to_many, instead of
in alter_db_table itself (more implementations).

Backport of 1edfa155e3 from master

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