Opened 9 years ago

Closed 3 years ago

Last modified 16 months ago

#23916 closed Bug (fixed)

makemigrations does not detect/like model name case changes

Reported by: Sven Coenye Owned by: Adam Johnson
Component: Migrations Version: dev
Severity: Normal Keywords:
Cc: info+coding@… Triage Stage: Ready for checkin
Has patch: yes Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description

Starting with

class Evidence(models.Model):
    rubrictype = models.ForeignKey('Rubrictype')

class Rubrictype(models.Model):
    type_code = models.CharField(max_length=1)

Make the initial migration:

$ ./manage.py makemigrations
Migrations for 'as_migrations':
  0001_initial.py:
    - Create model Evidence
    - Create model Rubrictype
    - Add field rubrictype to evidence

Change the name of Rubrictype to RubricType:

class Evidence(models.Model):
    rubrictype = models.ForeignKey('RubricType')

class RubricType(models.Model):
    type_code = models.CharField(max_length=1)

Generate the migration:

$ ./manage.py makemigrations
Migrations for 'as_migrations':
  0002_auto_20141125_1930.py:
    - Alter field rubrictype on evidence

Django does not detect the name change on the RubricType model itself. No confirmation is requested for the name change and no operation is generated. The problem is that any subsequent makemigrations run will generate the same operation ad infinitum:

$ ./manage.py makemigrations
Migrations for 'as_migrations':
  0003_auto_20141125_1930.py:
    - Alter field rubrictype on evidence

If instead the name is changed to RubricXype:

class Evidence(models.Model):
    rubrictype = models.ForeignKey('RubricXype')

class RubricXype(models.Model):
    type_code = models.CharField(max_length=1)

the corresponding migration becomes

$ ./manage.py makemigrations
Did you rename the as_migrations.Rubrictype model to RubricXype? [y/N] y
Migrations for 'as_migrations':
  0002_auto_20141125_1956.py:
    - Rename model Rubrictype to RubricXype

This migration generates a RenameModel operation only and any subsequent makemigrations runs will properly report "No changes detected". So it appears the change detector does not pick up on capitalization changes in model names.

Trying to work around by adding a

migrations.RenameModel(
    old_name='Rubrictype',
    new_name='RubricType',
)

to the auto generated operations results in a ValueError exception when makemigrations is run again:

$ ./manage.py makemigrations
Traceback (most recent call last):
  File "manage.py", line 10, in <module>
    execute_from_command_line(sys.argv)
  File "/home/svencoenye/developer/django_test/lib/python2.7/site-packages/django/core/management/__init__.py", line 385, in execute_from_command_line
    utility.execute()
  File "/home/svencoenye/developer/django_test/lib/python2.7/site-packages/django/core/management/__init__.py", line 377, in execute
    self.fetch_command(subcommand).run_from_argv(self.argv)
  File "/home/svencoenye/developer/django_test/lib/python2.7/site-packages/django/core/management/base.py", line 288, in run_from_argv
    self.execute(*args, **options.__dict__)
  File "/home/svencoenye/developer/django_test/lib/python2.7/site-packages/django/core/management/base.py", line 338, in execute
    output = self.handle(*args, **options)
  File "/home/svencoenye/developer/django_test/lib/python2.7/site-packages/django/core/management/commands/makemigrations.py", line 111, in handle
    convert_apps=app_labels or None,
  File "/home/svencoenye/developer/django_test/lib/python2.7/site-packages/django/db/migrations/autodetector.py", line 42, in changes
    changes = self._detect_changes(convert_apps, graph)
  File "/home/svencoenye/developer/django_test/lib/python2.7/site-packages/django/db/migrations/autodetector.py", line 109, in _detect_changes
    self.old_apps = self.from_state.render(ignore_swappable=True)
  File "/home/svencoenye/developer/django_test/lib/python2.7/site-packages/django/db/migrations/state.py", line 89, in render
    model=lookup_model,
ValueError: Lookup failed for model referenced by field as_migrations.Evidence.rubrictype: as_migrations.RubricType

The sequence of the operations does not matter. Neither does substituting the RenameModel operation for the AlterField operation.

(Looking at the next to last entry in the traceback, the autodetector seems to be looking for the new name in the old_apps state?)

It is possible, however, to go the long way around and use two separate migrations: Rubrictype -> RubricXype. RubricXype -> RubricType works without getting the migration state stuck and does not throw an exception.

Change History (16)

comment:1 Changed 9 years ago by Tim Graham

Triage Stage: UnreviewedAccepted

comment:2 Changed 9 years ago by Markus Holtermann

Cc: info+coding@… added

Thank you for the report. The problem you ran into relates to the fact that the migration internally don't care about case sensitivity of model names (ProjectState.models has a dictionary whose keys are (app_label, model_name) where the latter is lower cased).

Your work around seems to be valid. I'd need more info to figure out why adding the RenameModel manually fails.

comment:3 Changed 8 years ago by Sven Coenye

Sorry for the delayed response. I did not realize my e-mail address was missing from the preferences.

Is there anything I can do to provide more info on the RenameModel failure?

comment:4 Changed 8 years ago by Tim Graham

See #25429 for a probable duplicate (but please check when this is fixed and reopen it if not).

comment:5 Changed 7 years ago by Tim Graham

#26752 seems to be another symptom (closed as duplicate, but reopen if not).

comment:6 Changed 6 years ago by Anton Samarchyan

This is a duplicate of #27297

comment:7 Changed 3 years ago by Adam Johnson

Has patch: set
Owner: changed from nobody to Adam Johnson
Status: newassigned

comment:8 Changed 3 years ago by Mariusz Felisiak

Needs tests: set
Version: 1.7master

comment:9 in reply to:  8 Changed 3 years ago by Daniel S

Pardon my ignorance, but does this recent activity mean something is being done about this bug? I've only just run into it (changed a model name in casing only and now have infinite migration detection), so I'd be interested in finding a workaround. Replying to felixxm:

comment:10 Changed 3 years ago by Adam Johnson

Yes, there's a pull request - see the "Pull Requests" row in the table at the top describing the issue.

comment:11 Changed 3 years ago by Dustin Harrison

I hit this issue with Django 2.2.11.

  • Renamed several models with a case change only
  • Generated a migration with makemigrations
  • Subsequent migrations would always detect a change.
  • Ported Adam's patch to 2.2.12
  • makemigrations no longer detects changes

There were no conflicts in the patch.

comment:12 Changed 3 years ago by Adam Johnson

Needs tests: unset

comment:13 Changed 3 years ago by Mariusz Felisiak

Triage Stage: AcceptedReady for checkin

comment:14 Changed 3 years ago by Mariusz Felisiak <felisiak.mariusz@…>

Resolution: fixed
Status: assignedclosed

In 9e1b6b8:

Fixed #23916 -- Allowed makemigrations to handle related model name case changes.

Made autodetector ignore related model name case changes so unnecessary
migrations are not created.

comment:15 Changed 16 months ago by GitHub <noreply@…>

In 1e2e1be:

Fixed #33515 -- Prevented recreation of migration for ManyToManyField to lowercased swappable setting.

Thanks Chris Lee for the report.

Regression in 43289707809c814a70f0db38ca4f82f35f43dbfd.

Refs #23916.

comment:16 Changed 16 months ago by Mariusz Felisiak <felisiak.mariusz@…>

In 760b7e7f:

[4.0.x] Fixed #33515 -- Prevented recreation of migration for ManyToManyField to lowercased swappable setting.

Thanks Chris Lee for the report.

Regression in 43289707809c814a70f0db38ca4f82f35f43dbfd.

Refs #23916.
Backport of 1e2e1be02bdf0fe4add0d0279dbca1d74ae28ad7 from main

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