修复'列已经存在'Django迁移错误?
我收到的时候我尝试运行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'类,但这不会干。我不知道如何解决这个问题。
如果travel.country
字段已存在于数据库中,则无法运行迁移。您可以使用--fake
选项将迁移标记为已应用,而不实际运行SQL。
./manage.py migrate activities 0002_auto_20170731_1939 --fake
谢谢。迁移无误地运行。但我仍然很想知道为什么我要获得可交换的依赖关系指令和两个迁移文件0001_initial_.py和0002_auto _....你认为这是因为我有一个外键作为文章I穿越应用程序边界参考建议?您是否在使用您编写的Django应用程序时遇到此问题?谢谢! – William
我不知道为什么你在这种情况下结束了两次迁移。这可能是因为你的应用程序具有循环依赖关系。我不确定我是否同意链接文章的建议,以获得单个单一应用程序。你可能会发现[这个谈话](https://skillsmatter.com/skillscasts/7129-encapsulated-django-keeping-your-apps-small-focused-and-free-of-circular-dependencies)有趣。 – Alasdair
呃。我刚刚注意到,当我运行最后一次迁移时,不同模型中的新列没有添加(因为我正在迁移活动应用程序,所以我会这样做)。所以我改变了名字,迫使Django看到了变化,而且确实如此。但是当我运行'makemigrations'时,Django抱怨说它无法通过旧名称找到新列。这些迁移令人生气。 – William
正如Alasdair所说,您无法覆盖现有列。当我做出这样的事情时 - 必须删除表格并用清晰的迁移重新创建新表格。
为一个ForeignKey或抽象类ManyToManyField,添加相关的名字是这样的: related_name = “%(app_label)■_%(类)s_related”,
如果您还使用related_query_name,添加此: related_query_name =“%(app_label)s _%(class)ss”,
您是否为现有数据库创建了迁移,或者您刚启动了此项目? – Alasdair
这是对现有数据库的迁移。迁移曾经运行,但现在他们没有。奇怪的是,我有一段时间没有改变相关的活动模型。 – William