class Post(models.Model):
title = models.CharField(max_length=200, null=True)
date_posted = models.DateTimeField()
class Meta:
indexes = [models.Index(fields=['-date_posted'])]
Problem description and steps to reproduce
Migration raises exception when it calls _delete_indexes in schema.py and the previous migration has an index with a field that starts with a hyphen (descending order).
Make a project with the model above and two migrations:
Run python manage.py migrate on an empty database.
Expected behavior and actual behavior
The both migrations should succeed.
Instead, the migration 0002_alter_post_title breaks with the exception django.core.exceptions.FieldDoesNotExist: Post has no field named '-date_posted'
Error message/stack trace
Traceback (most recent call last):
File "/home/user/PycharmProjects/idxtest/manage.py", line 22, in <module>
main()
File "/home/user/PycharmProjects/idxtest/manage.py", line 18, in main
execute_from_command_line(sys.argv)
File "/home/user/.local/share/virtualenvs/idxtest-Z4Fcl3b8/lib/python3.10/site-packages/django/core/management/__init__.py", line 442, in execute_from_command_line
utility.execute()
File "/home/user/.local/share/virtualenvs/idxtest-Z4Fcl3b8/lib/python3.10/site-packages/django/core/management/__init__.py", line 436, in execute
self.fetch_command(subcommand).run_from_argv(self.argv)
File "/home/user/.local/share/virtualenvs/idxtest-Z4Fcl3b8/lib/python3.10/site-packages/django/core/management/base.py", line 413, in run_from_argv
self.execute(*args, **cmd_options)
File "/home/user/.local/share/virtualenvs/idxtest-Z4Fcl3b8/lib/python3.10/site-packages/django/core/management/base.py", line 459, in execute
output = self.handle(*args, **options)
File "/home/user/.local/share/virtualenvs/idxtest-Z4Fcl3b8/lib/python3.10/site-packages/django/core/management/base.py", line 107, in wrapper
res = handle_func(*args, **kwargs)
File "/home/user/.local/share/virtualenvs/idxtest-Z4Fcl3b8/lib/python3.10/site-packages/django/core/management/commands/migrate.py", line 356, in handle
post_migrate_state = executor.migrate(
File "/home/user/.local/share/virtualenvs/idxtest-Z4Fcl3b8/lib/python3.10/site-packages/django/db/migrations/executor.py", line 135, in migrate
state = self._migrate_all_forwards(
File "/home/user/.local/share/virtualenvs/idxtest-Z4Fcl3b8/lib/python3.10/site-packages/django/db/migrations/executor.py", line 167, in _migrate_all_forwards
state = self.apply_migration(
File "/home/user/.local/share/virtualenvs/idxtest-Z4Fcl3b8/lib/python3.10/site-packages/django/db/migrations/executor.py", line 252, in apply_migration
state = migration.apply(state, schema_editor)
File "/home/user/.local/share/virtualenvs/idxtest-Z4Fcl3b8/lib/python3.10/site-packages/django/db/migrations/migration.py", line 132, in apply
operation.database_forwards(
File "/home/user/.local/share/virtualenvs/idxtest-Z4Fcl3b8/lib/python3.10/site-packages/django/db/migrations/operations/fields.py", line 235, in database_forwards
schema_editor.alter_field(from_model, from_field, to_field)
File "/home/user/.local/share/virtualenvs/idxtest-Z4Fcl3b8/lib/python3.10/site-packages/django/db/backends/base/schema.py", line 893, in alter_field
self._alter_field(
File "/home/user/.local/share/virtualenvs/idxtest-Z4Fcl3b8/lib/python3.10/site-packages/mssql/schema.py", line 618, in _alter_field
indexes_dropped = self._delete_indexes(model, old_field, new_field)
File "/home/user/.local/share/virtualenvs/idxtest-Z4Fcl3b8/lib/python3.10/site-packages/mssql/schema.py", line 926, in _delete_indexes
columns = [model._meta.get_field(field).column for field in index.fields]
File "/home/user/.local/share/virtualenvs/idxtest-Z4Fcl3b8/lib/python3.10/site-packages/mssql/schema.py", line 926, in <listcomp>
columns = [model._meta.get_field(field).column for field in index.fields]
File "/home/user/.local/share/virtualenvs/idxtest-Z4Fcl3b8/lib/python3.10/site-packages/django/db/models/options.py", line 683, in get_field
raise FieldDoesNotExist(
django.core.exceptions.FieldDoesNotExist: Post has no field named '-date_posted'
Any other details that can be helpful
The problem is this line in _delete_indexes from schema.py
columns = [model._meta.get_field(field).column for field in index.fields]
If the index.fields has a field in descending order, that field has a hyphen before the name and the get_field fails. The offending line should use index.fields_orders instead:
columns = [model._meta.get_field(field).column for field, _ in index.fields_orders]
Software versions
Table schema and Model
Database Connection Settings
Problem description and steps to reproduce Migration raises exception when it calls _delete_indexes in schema.py and the previous migration has an index with a field that starts with a hyphen (descending order).
Make a project with the model above and two migrations:
migrations/0001_initial.py
migrations/0002_alter_post_title.py
Run
python manage.py migrate
on an empty database.Expected behavior and actual behavior The both migrations should succeed.
Instead, the migration 0002_alter_post_title breaks with the exception
django.core.exceptions.FieldDoesNotExist: Post has no field named '-date_posted'
Error message/stack trace
Any other details that can be helpful The problem is this line in _delete_indexes from schema.py
If the index.fields has a field in descending order, that field has a hyphen before the name and the get_field fails. The offending line should use index.fields_orders instead: