6
votes

I'm getting a "column of relation already exists" error when I try to run the Django migrate command:

Operations to perform:
  Synchronize unmigrated apps: signin, django_rq, gis, staticfiles, admindocs, messages, pipeline, test_without_migrations, django_extensions
  Apply all migrations: profile, activities, contenttypes, # plus other modules...
Synchronizing apps without migrations:
  Creating tables...
    Running deferred SQL...
  Installing custom SQL...
Running migrations:
  Rendering model states... DONE
  Applying activities.0002_auto_20170731_1939...Traceback (most recent call last):
  File "manage.py", line 10, in <module>
    execute_from_command_line(sys.argv)
  File "/srv/http/example.com/venvs/4dc40e5fc12700640a30ae0f040aa07ffc8aa1c5/local/lib/python2.7/site-packages/django/core/management/__init__.py", line 338, in execute_from_command_line
    utility.execute()
  File "/srv/http/example.com/venvs/4dc40e5fc12700640a30ae0f040aa07ffc8aa1c5/local/lib/python2.7/site-packages/django/core/management/__init__.py", line 330, in execute
    self.fetch_command(subcommand).run_from_argv(self.argv)
  File "/srv/http/example.com/venvs/4dc40e5fc12700640a30ae0f040aa07ffc8aa1c5/local/lib/python2.7/site-packages/django/core/management/base.py", line 393, in run_from_argv
    self.execute(*args, **cmd_options)
  File "/srv/http/example.com/venvs/4dc40e5fc12700640a30ae0f040aa07ffc8aa1c5/local/lib/python2.7/site-packages/django/core/management/base.py", line 444, in execute
    output = self.handle(*args, **options)
  File "/srv/http/example.com/venvs/4dc40e5fc12700640a30ae0f040aa07ffc8aa1c5/local/lib/python2.7/site-packages/django/core/management/commands/migrate.py", line 222, in handle
    executor.migrate(targets, plan, fake=fake, fake_initial=fake_initial)
  File "/srv/http/example.com/venvs/4dc40e5fc12700640a30ae0f040aa07ffc8aa1c5/local/lib/python2.7/site-packages/django/db/migrations/executor.py", line 110, in migrate
    self.apply_migration(states[migration], migration, fake=fake, fake_initial=fake_initial)
  File "/srv/http/example.com/venvs/4dc40e5fc12700640a30ae0f040aa07ffc8aa1c5/local/lib/python2.7/site-packages/django/db/migrations/executor.py", line 148, in apply_migration
    state = migration.apply(state, schema_editor)
  File "/srv/http/example.com/venvs/4dc40e5fc12700640a30ae0f040aa07ffc8aa1c5/local/lib/python2.7/site-packages/django/db/migrations/migration.py", line 115, in apply
    operation.database_forwards(self.app_label, schema_editor, old_state, project_state)
  File "/srv/http/example.com/venvs/4dc40e5fc12700640a30ae0f040aa07ffc8aa1c5/local/lib/python2.7/site-packages/django/db/migrations/operations/fields.py", line 62, in database_forwards
    field,
  File "/srv/http/example.com/venvs/4dc40e5fc12700640a30ae0f040aa07ffc8aa1c5/local/lib/python2.7/site-packages/django/contrib/gis/db/backends/postgis/schema.py", line 94, in add_field
    super(PostGISSchemaEditor, self).add_field(model, field)
  File "/srv/http/example.com/venvs/4dc40e5fc12700640a30ae0f040aa07ffc8aa1c5/local/lib/python2.7/site-packages/django/db/backends/base/schema.py", line 398, in add_field
    self.execute(sql, params)
  File "/srv/http/example.com/venvs/4dc40e5fc12700640a30ae0f040aa07ffc8aa1c5/local/lib/python2.7/site-packages/django/db/backends/base/schema.py", line 111, in execute
    cursor.execute(sql, params)
  File "/srv/http/example.com/venvs/4dc40e5fc12700640a30ae0f040aa07ffc8aa1c5/local/lib/python2.7/site-packages/django/db/backends/utils.py", line 79, in execute
    return super(CursorDebugWrapper, self).execute(sql, params)
  File "/srv/http/example.com/venvs/4dc40e5fc12700640a30ae0f040aa07ffc8aa1c5/local/lib/python2.7/site-packages/django/db/backends/utils.py", line 64, in execute
    return self.cursor.execute(sql, params)
  File "/srv/http/example.com/venvs/4dc40e5fc12700640a30ae0f040aa07ffc8aa1c5/local/lib/python2.7/site-packages/django/db/utils.py", line 97, in __exit__
    six.reraise(dj_exc_type, dj_exc_value, traceback)
  File "/srv/http/example.com/venvs/4dc40e5fc12700640a30ae0f040aa07ffc8aa1c5/local/lib/python2.7/site-packages/django/db/backends/utils.py", line 64, in execute
    return self.cursor.execute(sql, params)
django.db.utils.ProgrammingError: column "country_id" of relation "travel" already exists

The Travel class inherits from the Activities class:

# activities/models.py
from profile.models import Country

class Activity(models.Model):
    host = models.ForeignKey(User)
    # other fields...

    class Meta:
        abstract = True

class Travel(Activity):
    start_date = models.DateField()
    country = models.ForeignKey(Country)
    # other fields...

The country class being referenced by the foreign key is in another module. It's essentially a lookup table that will contain a code (abbreviation) and name for each country:

# profile/models.py
class Country(models.Model):
    country_cd = models.CharField(max_length=2)
    descrip = models.CharField(max_length=50)

I don't see anything out of the ordinary in the migrations file other than the fact that there are two migration files for activities (which I don't quite understand):

# activities/migrations/0001_initial.py
class Migration(migrations.Migration):

    dependencies = [
    ]

    operations = [
        migrations.CreateModel(
            name='Travel',
            fields=[
                ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
                ('name', models.CharField(max_length=256)),
                # other fields but none that reference Country
            ],
            options={
                'db_table': 'travel',
            },
        ),
    ]

# activities/migrations/0002_auto_20170731_1939.py
class Migration(migrations.Migration):

    dependencies = [
        migrations.swappable_dependency(settings.AUTH_USER_MODEL),
        ('profile', '0001_initial'),
        ('activities', '0001_initial'),
    ]

    operations = [
        migrations.AddField(
            model_name='travel',
            name='country',
            field=models.ForeignKey(to='profile.Country'),
        ),
        migrations.AddField(
            model_name='travel',
            name='host',
            field=models.ForeignKey(to=settings.AUTH_USER_MODEL),
        ),
        # other fields...
    ]

I don't understand why I'm getting this error. I've noticed that I don't have this problem in other models that declare foreign key relations. However,in all of those models either the foreign key relation is to auth.models.User or to another class within the same model file. I read an article Tips for Building High-Quality Django Apps at Scale recently in which the author said you can have problems running migrations if you have cross-app foreign keys, so maybe the problem is related to that. I could recreate the 'Country' class inside the activities module but that wouldn't be DRY. I'm not sure how to resolve this problem.

4
Have you created migrations for an existing database, or have you just started this project?Alasdair
This was a migration for an existing database. The migrations used to run but now they don't. The odd thing is that I haven't changed the activities models in question for some time.Jim

4 Answers

29
votes

If the travel.country field already exists in the database, then it isn't possible to run the migration. You can use the --fake option to mark the migration as applied, without actually running the SQL.

./manage.py migrate activities 0002_auto_20170731_1939 --fake
0
votes

As said Alasdair, you can't override existing column. When I made such thing - have to drop tables and recreate new with clear migrate.

0
votes

for a ForeignKey or a ManyToManyField in an abstract class, add a related name like this: related_name="%(app_label)s_%(class)s_related",

if you also use related_query_name, add this: related_query_name="%(app_label)s_%(class)ss",

0
votes

If you are working with custom migrations and your migrations only partially ran because of an error, you might get this error.

To resolve it, you can drop the column in the DB shell (./manage.py dbshell):

ALTER TABLE myapp_mymodel DROP COLUMN your_column;

ONLY DO THIS IF THE COLUMN HAS NO DATA AND WAS ACCIDENTALLY CREATED WHEN YOU WERE CREATING A CUSTOM MIGRATION. THIS WILL ERASE ALL THE DATA IN THE COLUMN AND POSSIBLY SCREW UP DJANGO IF DONE OTHERWISE.