#27915: Defining Index object in Meta.indexes in abstract class causes failure
during migration of sub-classes
-------------------------------------+-------------------------------------
               Reporter:  Tommy      |          Owner:  nobody
  Beadle                             |
                   Type:  Bug        |         Status:  new
              Component:  Database   |        Version:  1.11
  layer (models, ORM)                |
               Severity:  Normal     |       Keywords:
           Triage Stage:             |      Has patch:  0
  Unreviewed                         |
    Needs documentation:  0          |    Needs tests:  0
Patch needs improvement:  0          |  Easy pickings:  0
                  UI/UX:  0          |
-------------------------------------+-------------------------------------
 If I define an abstract model like this:

 {{{#!python
 class AbstractClass(models.Model):
     text = models.TextField()
     class Meta:
         abstract=True
         indexes = [
             models.indexes.Index(fields=['text']),
         ]
 }}}

 and then subclass it:

 {{{#!python
 class NewClass1(AbstractClass):
     pass

 class NewClass2(AbstractClass):
     pass
 }}}

 Then, when I make the migrations, an index with the same ID is created for
 the sub-classes:

 {{{
 (venv) $ ./manage.py makemigrations myapp
 Migrations for 'myapp':
   myapp/migrations/0001_initial.py
     - Create model NewClass1
     - Create model NewClass2
     - Create index myapp_abstr_text_5dfb11_idx on field(s) text of model
 newclass2
     - Create index myapp_abstr_text_5dfb11_idx on field(s) text of model
 newclass1
 }}}

 which then results in the following traceback when performing the
 migration:

 {{{
 (venv) $ ./manage.py migrate
 <snip>
 Traceback (most recent call last):
   File "./manage.py", line 22, in <module>
     execute_from_command_line(sys.argv)
   File "/home/tbeadle/venv/lib/python3.6/site-
 packages/django/core/management/__init__.py", line 363, in
 execute_from_command_line
     utility.execute()
   File "/home/tbeadle/venv/lib/python3.6/site-
 packages/django/core/management/__init__.py", line 355, in execute
     self.fetch_command(subcommand).run_from_argv(self.argv)
   File "/home/tbeadle/venv/lib/python3.6/site-
 packages/django/core/management/base.py", line 283, in run_from_argv
     self.execute(*args, **cmd_options)
   File "/home/tbeadle/venv/lib/python3.6/site-
 packages/django/core/management/base.py", line 330, in execute
     output = self.handle(*args, **options)
   File "/home/tbeadle/venv/lib/python3.6/site-
 packages/django/core/management/commands/migrate.py", line 204, in handle
     fake_initial=fake_initial,
   File "/home/tbeadle/venv/lib/python3.6/site-
 packages/django/db/migrations/executor.py", line 115, in migrate
     state = self._migrate_all_forwards(state, plan, full_plan, fake=fake,
 fake_initial=fake_initial)
   File "/home/tbeadle/venv/lib/python3.6/site-
 packages/django/db/migrations/executor.py", line 145, in
 _migrate_all_forwards
     state = self.apply_migration(state, migration, fake=fake,
 fake_initial=fake_initial)
   File "/home/tbeadle/venv/lib/python3.6/site-
 packages/django/db/migrations/executor.py", line 244, in apply_migration
     state = migration.apply(state, schema_editor)
   File "/home/tbeadle/venv/lib/python3.6/site-
 packages/django/db/migrations/migration.py", line 129, in apply
     operation.database_forwards(self.app_label, schema_editor, old_state,
 project_state)
   File "/home/tbeadle/venv/lib/python3.6/site-
 packages/django/db/migrations/operations/models.py", line 785, in
 database_forwards
     schema_editor.add_index(model, self.index)
   File "/home/tbeadle/venv/lib/python3.6/site-
 packages/django/db/backends/base/schema.py", line 330, in add_index
     self.execute(index.create_sql(model, self))
   File "/home/tbeadle/venv/lib/python3.6/site-
 packages/django/db/backends/base/schema.py", line 119, in execute
     cursor.execute(sql, params)
   File "/home/tbeadle/venv/lib/python3.6/site-
 packages/django/db/backends/utils.py", line 80, in execute
     return super(CursorDebugWrapper, self).execute(sql, params)
   File "/home/tbeadle/venv/lib/python3.6/site-
 packages/django/db/backends/utils.py", line 65, in execute
     return self.cursor.execute(sql, params)
   File "/home/tbeadle/venv/lib/python3.6/site-
 packages/django/db/utils.py", line 94, in __exit__
     six.reraise(dj_exc_type, dj_exc_value, traceback)
   File "/home/tbeadle/venv/lib/python3.6/site-
 packages/django/utils/six.py", line 685, in reraise
     raise value.with_traceback(tb)
   File "/home/tbeadle/venv/lib/python3.6/site-
 packages/django/db/backends/utils.py", line 65, in execute
     return self.cursor.execute(sql, params)
   File "/home/tbeadle/venv/lib/python3.6/site-
 packages/django/db/backends/sqlite3/base.py", line 328, in execute
     return Database.Cursor.execute(self, query, params)
 django.db.utils.OperationalError: index myapp_abstr_text_5dfb11_idx
 already exists
 }}}

 This is apparently because the Index object gets created during creation
 of the abstract class and reused in the subclasses.  Instead, the name
 needs to be generated when it gets copied to the sub-classes.

--
Ticket URL: <https://code.djangoproject.com/ticket/27915>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.

-- 
You received this message because you are subscribed to the Google Groups 
"Django updates" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To post to this group, send email to [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-updates/050.55fa527fe1f3ee0fe5f11dc7bbde3143%40djangoproject.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to