Opened 10 years ago

Closed 10 years 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 Conrad 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 by Claus Conrad, 10 years ago

Cc: lists@… added

comment:2 by Baptiste Mispelon, 10 years ago

Triage Stage: UnreviewedAccepted

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 by Markus Holtermann, 10 years ago

Cc: info@… added

comment:4 by ANUBHAV JOSHI, 10 years ago

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.

If such FieldError arises, then it should be caught and then we can create a whole new Bar or something like that.
Reordering will create subclass first, will it not be wrong creating a subclassbefore its base class

Thoughts?

Last edited 10 years ago by ANUBHAV JOSHI (previous) (diff)

comment:5 by Andrew Godwin, 10 years ago

Resolution: fixed
Status: newclosed

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