﻿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
30362	Note partial indexes and constraints restrictions with abstract base classes.	Tim Dawborn	Mariusz Felisiak	"When specifying a `condition` on an `Index`, one has to provide the `name` of the index as a string: https://docs.djangoproject.com/en/2.2/ref/models/indexes/#django.db.models.Index.condition

This results in it being impossible to define an `Index` with a `condition` as a model inheritance base class, as the `name` of the index needs to be unique across the whole database, but it will be the same for all subclasses of the base class.

Example:

{{{
class BaseModel(models.Model):
  deleted_at = models.DateTimeField(blank=True, null=True)

  class Meta:
    abstract = True
    indexes = [
      Index(fields=['id'], condition=Q(deleted_at__isnull=True), name='id_nondeleted'),
    ]


class Foo(BaseModel):
  pass


class Bar(BaseModel):
  pass
}}}


{{{
(ve)12:55:41 ubuntu@local bugreport$ python manage.py makemigrations myapp
Migrations for 'myapp':
  myapp/migrations/0001_initial.py
    - Create model Bar
    - Create model Foo
    - Create index id_nondeleted on field(s) id of model foo
    - Create index id_nondeleted on field(s) id of model bar
(ve)12:55:42 ubuntu@local bugreport$ python manage.py migrate myapp
Operations to perform:
  Apply all migrations: myapp
Running migrations:
  Applying myapp.0001_initial...Traceback (most recent call last):
  File ""/tmp/django-test/ve/lib/python3.7/site-packages/django/db/backends/utils.py"", line 82, in _execute
    return self.cursor.execute(sql)
  File ""/tmp/django-test/ve/lib/python3.7/site-packages/django/db/backends/sqlite3/base.py"", line 381, in execute
    return Database.Cursor.execute(self, query)
sqlite3.OperationalError: index id_nondeleted already exists

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File ""manage.py"", line 21, in <module>
    main()
  File ""manage.py"", line 17, in main
    execute_from_command_line(sys.argv)
  File ""/tmp/django-test/ve/lib/python3.7/site-packages/django/core/management/__init__.py"", line 381, in execute_from_command_line
    utility.execute()
  File ""/tmp/django-test/ve/lib/python3.7/site-packages/django/core/management/__init__.py"", line 375, in execute
    self.fetch_command(subcommand).run_from_argv(self.argv)
  File ""/tmp/django-test/ve/lib/python3.7/site-packages/django/core/management/base.py"", line 323, in run_from_argv
    self.execute(*args, **cmd_options)
  File ""/tmp/django-test/ve/lib/python3.7/site-packages/django/core/management/base.py"", line 364, in execute
    output = self.handle(*args, **options)
  File ""/tmp/django-test/ve/lib/python3.7/site-packages/django/core/management/base.py"", line 83, in wrapped
    res = handle_func(*args, **kwargs)
  File ""/tmp/django-test/ve/lib/python3.7/site-packages/django/core/management/commands/migrate.py"", line 234, in handle
    fake_initial=fake_initial,
  File ""/tmp/django-test/ve/lib/python3.7/site-packages/django/db/migrations/executor.py"", line 117, in migrate
    state = self._migrate_all_forwards(state, plan, full_plan, fake=fake, fake_initial=fake_initial)
  File ""/tmp/django-test/ve/lib/python3.7/site-packages/django/db/migrations/executor.py"", line 147, in _migrate_all_forwards
    state = self.apply_migration(state, migration, fake=fake, fake_initial=fake_initial)
  File ""/tmp/django-test/ve/lib/python3.7/site-packages/django/db/migrations/executor.py"", line 245, in apply_migration
    state = migration.apply(state, schema_editor)
  File ""/tmp/django-test/ve/lib/python3.7/site-packages/django/db/migrations/migration.py"", line 124, in apply
    operation.database_forwards(self.app_label, schema_editor, old_state, project_state)
  File ""/tmp/django-test/ve/lib/python3.7/site-packages/django/db/migrations/operations/models.py"", line 744, in database_forwards
    schema_editor.add_index(model, self.index)
  File ""/tmp/django-test/ve/lib/python3.7/site-packages/django/db/backends/base/schema.py"", line 335, in add_index
    self.execute(index.create_sql(model, self), params=None)
  File ""/tmp/django-test/ve/lib/python3.7/site-packages/django/db/backends/base/schema.py"", line 137, in execute
    cursor.execute(sql, params)
  File ""/tmp/django-test/ve/lib/python3.7/site-packages/django/db/backends/utils.py"", line 99, in execute
    return super().execute(sql, params)
  File ""/tmp/django-test/ve/lib/python3.7/site-packages/django/db/backends/utils.py"", line 67, in execute
    return self._execute_with_wrappers(sql, params, many=False, executor=self._execute)
  File ""/tmp/django-test/ve/lib/python3.7/site-packages/django/db/backends/utils.py"", line 76, in _execute_with_wrappers
    return executor(sql, params, many, context)
  File ""/tmp/django-test/ve/lib/python3.7/site-packages/django/db/backends/utils.py"", line 84, in _execute
    return self.cursor.execute(sql, params)
  File ""/tmp/django-test/ve/lib/python3.7/site-packages/django/db/utils.py"", line 89, in __exit__
    raise dj_exc_value.with_traceback(traceback) from exc_value
  File ""/tmp/django-test/ve/lib/python3.7/site-packages/django/db/backends/utils.py"", line 82, in _execute
    return self.cursor.execute(sql)
  File ""/tmp/django-test/ve/lib/python3.7/site-packages/django/db/backends/sqlite3/base.py"", line 381, in execute
    return Database.Cursor.execute(self, query)
django.db.utils.OperationalError: index id_nondeleted already exists
}}}

"	Bug	closed	Database layer (models, ORM)	2.2	Release blocker	fixed	inheritance index name	Ian Foote Mads Jensen Can Sarıgöl Alan Justino da Silva	Accepted	1	0	0	0	0	0
