Opened 14 months ago

Closed 7 months ago

#21890 closed Bug (fixed)

django.core.exceptions.FieldError: Local field ... in class ... clashes with field of similar name from base class ...

Reported by: claus Owned by:
Component: Migrations Version: 1.7-alpha-1
Severity: Normal Keywords:
Cc: lists@…, info@… Triage Stage: Accepted
Has patch: no Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description

Moving a field from a subclass to its base class results in the above error due to the operations being in the wrong order. Reordering the operations allowed me to run the migration.

Change History (5)

comment:1 Changed 14 months ago by claus

  • Cc lists@… added
  • Needs documentation unset
  • Needs tests unset
  • Patch needs improvement unset

comment:2 Changed 14 months ago by bmispelon

  • Triage Stage changed from Unreviewed to Accepted

Hi,

I can reproduce the error you describer with the following models:

# First version
class Foo(models.Model):
    pass

class Bar(Foo):
    baz = models.IntegerField(default=42)

# Second version
class Foo(models.Model):
    baz = models.IntegerField(default=42)

class Bar(Foo):
    pass

After creating the version, I run makemigrations, then change my models to the second version and run makemigrations again.
After that, running migrate triggers the following error:

Running migrations:
  Applying bug21890.0001_initial... OK
  Applying bug21890.0002_auto_20140129_0404...Traceback (most recent call last):
  File "manage.py", line 10, in <module>
    execute_from_command_line(sys.argv)
  File "./django/core/management/__init__.py", line 427, in execute_from_command_line
    utility.execute()
  File "./django/core/management/__init__.py", line 419, in execute
    self.fetch_command(subcommand).run_from_argv(self.argv)
  File "./django/core/management/base.py", line 287, in run_from_argv
    self.execute(*args, **options.__dict__)
  File "./django/core/management/base.py", line 336, in execute
    output = self.handle(*args, **options)
  File "./django/core/management/commands/migrate.py", line 145, in handle
    executor.migrate(targets, plan, fake=options.get("fake", False))
  File "./django/db/migrations/executor.py", line 60, in migrate
    self.apply_migration(migration, fake=fake)
  File "./django/db/migrations/executor.py", line 94, in apply_migration
    migration.apply(project_state, schema_editor)
  File "./django/db/migrations/migration.py", line 97, in apply
    operation.database_forwards(self.app_label, schema_editor, project_state, new_state)
  File "./django/db/migrations/operations/fields.py", line 28, in database_forwards
    to_model = to_state.render().get_model(app_label, self.model_name)
  File "./django/db/migrations/state.py", line 48, in render
    model.render(self.apps)
  File "./django/db/migrations/state.py", line 213, in render
    body,
  File "./django/db/models/base.py", line 244, in __new__
    'base class %r' % (field.name, name, base.__name__)
django.core.exceptions.FieldError: Local field 'baz' in class 'Bar' clashes with field of similar name from base class 'Foo'

Thanks.

comment:3 Changed 13 months ago by MarkusH

  • Cc info@… added

comment:4 Changed 13 months ago by anubhav9042

From what I have understood, the changes occur first in class Foo, thus it now has a field baz. Then when applying changes in class Bar, when it sees that parent class is Foo and Bar has a field of same name as that in Foo, it raises FieldError.

What I think of solving this:
If such FieldError arises, then it should be caught and then we can create a whole new Bar or something like that.

Thoughts?

Version 0, edited 13 months ago by anubhav9042 (next)

comment:5 Changed 7 months ago by andrewgodwin

  • Resolution set to fixed
  • Status changed from new to closed

This has since been fixed by the autodetector rewrite. You will lose data with this move, as it's a column being moved across tables; to avoid this, you would have to manually create a migration that made the new column, copied data across, and then removed the old column, and then gave the new column the correct name (it can't have it to start with as it would clash, like the original error here)

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