2017-08-01 44 views
1

我收到的時候我嘗試運行Django的遷移命令「關係的列已經存在」錯誤:修復'列已經存在'Django遷移錯誤?

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 

的旅遊類從活動類繼承:

# 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... 

國家由外鍵引用的類位於另一個模塊中。它本質上是一個查找表將包含每個國家代碼(簡稱)和 名稱:

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

我看不出有什麼出格的遷移普通的文件不是事實,其他的有兩種遷移活動文件(我不太明白):

# 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... 
    ] 

我不明白爲什麼我得到這個錯誤。我注意到在聲明外鍵關係的其他模型中我沒有這個問題。但是,在所有這些模型中,外鍵關係都是auth.models.User或同一模型文件中的另一個類。我最近閱讀了一篇文章Tips for Building High-Quality Django Apps at Scale,其中作者說如果您有跨應用程序外鍵,則可能會遇到遷移問題,所以問題可能與此有關。我可以在活動模塊內重新創建'Country'類,但這不會幹。我不知道如何解決這個問題。

+0

您是否爲現有數據庫創建了遷移,或者您剛啓動了此項目? – Alasdair

+0

這是對現有數據庫的遷移。遷移曾經運行,但現在他們沒有。奇怪的是,我有一段時間沒有改變相關的活動模型。 – William

回答

3

如果travel.country字段已存在於數據庫中,則無法運行遷移。您可以使用--fake選項將遷移標記爲已應用,而不實際運行SQL。

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

謝謝。遷移無誤地運行。但我仍然很想知道爲什麼我要獲得可交換的依賴關係指令和兩個遷移文件0001_initial_.py和0002_auto _....你認爲這是因爲我有一個外鍵作爲文章I穿越應用程序邊界參考建議?您是否在使用您編寫的Django應用程序時遇到此問題?謝謝! – William

+0

我不知道爲什麼你在這種情況下結束了兩次遷移。這可能是因爲你的應用程序具有循環依賴關係。我不確定我是否同意鏈接文章的建議,以獲得單個單一應用程序。你可能會發現[這個談話](https://skillsmatter.com/skillscasts/7129-encapsulated-django-keeping-your-apps-small-focused-and-free-of-circular-dependencies)有趣。 – Alasdair

+0

呃。我剛剛注意到,當我運行最後一次遷移時,不同模型中的新列沒有添加(因爲我正在遷移活動應用程序,所以我會這樣做)。所以我改變了名字,迫使Django看到了變化,而且確實如此。但是當我運行'makemigrations'時,Django抱怨說它無法通過舊名稱找到新列。這些遷移令人生氣。 – William

0

正如Alasdair所說,您無法覆蓋現有列。當我做出這樣的事情時 - 必須刪除表格並用清晰的遷移重新創建新表格。

0

爲一個ForeignKey或抽象類​​ManyToManyField,添加相關的名字是這樣的: related_name = 「%(app_label)■_%(類)s_related」,

如果您還使用related_query_name,添加此: related_query_name =「%(app_label)s _%(class)ss」,