对我的Django应用程序模型做了一些更改,并使用South将它们迁移到我的开发计算机上(迁移0004至0009)。但是当试图在服务器上迁移这些更改时,出现“GhostMigrations”错误。什么是Django South GhostMigrations异常以及如何调试它?
解释什么是ghost迁移,或者如何调试,没有太多好的内容。谷歌对这一个没有帮助,而提到鬼迁移的其他SO问题也不包括这一点(最有帮助的问题here主要是关于工作流)。 django-south IRC中有帮助的人对此说过鬼迁移:“这意味着南的历史(db中的一个表)记录了它认为已经应用的两个迁移,但是其迁移文件找不到” 。我试图弄清楚现在如何完成调试。
在此先感谢您的帮助。
这里的错误:
Traceback (most recent call last):
File "manage.py", line 14, in <module>
execute_manager(settings)
File "/home/username/webapps/myproject/lib/python2.6/django/core/management/__init__.py", line 438, in execute_manager
utility.execute()
File "/home/username/webapps/myproject/lib/python2.6/django/core/management/__init__.py", line 379, in execute
self.fetch_command(subcommand).run_from_argv(self.argv)
File "/home/username/webapps/myproject/lib/python2.6/django/core/management/base.py", line 191, in run_from_argv
self.execute(*args, **options.__dict__)
File "/home/username/webapps/myproject/lib/python2.6/django/core/management/base.py", line 220, in execute
output = self.handle(*args, **options)
File "/home/username/lib/python2.6/South-0.7.3-py2.6.egg/south/management/commands/migrate.py", line 105, in handle
ignore_ghosts = ignore_ghosts,
File "/home/username/lib/python2.6/South-0.7.3-py2.6.egg/south/migration/__init__.py", line 171, in migrate_app
applied = check_migration_histories(applied, delete_ghosts, ignore_ghosts)
File "/home/username/lib/python2.6/South-0.7.3-py2.6.egg/south/migration/__init__.py", line 88, in check_migration_histories
raise exceptions.GhostMigrations(ghosts)
south.exceptions.GhostMigrations:
! These migrations are in the database but not on disk:
<bodyguard: 0002_auto__add_field_asset_is_reserved__add_field_asset_is_created__add_fie>
<bodyguard: 0003_auto__del_field_asset_is_reserved__add_field_asset_is_assigned>
! I'm not trusting myself; either fix this yourself by fiddling
! with the south_migrationhistory table, or pass --delete-ghost-migrations
! to South to have it delete ALL of these records (this may not be good).
我很惊讶地看到,南方抱怨迁移在0002和0003,因为我这些变化个月前提出。我今天早些时候所做的改变是改变0004至0009.
这里是我的模型:
class Asset(models.Model):
title = models.CharField(max_length=200, blank=True, null=True)
user = models.ForeignKey(User, blank=True, null=True)
is_assigned = models.NullBooleanField(blank=True, null=True)
is_created = models.NullBooleanField(blank=True, null=True)
is_active = models.NullBooleanField(blank=True, null=True)
activation_date = models.DateTimeField(default=datetime.datetime.now, blank=True, null=True)
class AssetEdit(models.Model):
asset = models.ForeignKey(Asset, related_name="edits", blank=True, null=True)
update_date = models.DateTimeField(default=datetime.datetime.now, blank=True, null=True)
这里是南迁移文件夹的内容:
0001_initial.py
0001_initial.pyc
0002_auto__chg_field_asset_username__chg_field_asset_title__chg_field_asset.py
0002_auto__chg_field_asset_username__chg_field_asset_title__chg_field_asset.pyc
0003_auto__add_field_asset_is_reserved__add_field_asset_is_created__add_fie.py
0003_auto__add_field_asset_is_reserved__add_field_asset_is_created__add_fie.pyc
0004_auto__del_field_asset_is_reserved__add_field_asset_is_assigned.py
0004_auto__del_field_asset_is_reserved__add_field_asset_is_assigned.pyc
0005_auto__add_assetedit.py
0005_auto__add_assetedit.pyc
0006_auto__del_field_assetedit_user__add_field_assetedit_asset.py
0006_auto__del_field_assetedit_user__add_field_assetedit_asset.pyc
0007_auto__chg_field_assetedit_update_date.py
0007_auto__chg_field_assetedit_update_date.pyc
0008_auto__add_field_asset_activated_date.py
0008_auto__add_field_asset_activated_date.pyc
0009_auto__del_field_asset_activated_date__add_field_asset_activation_date.py
0009_auto__del_field_asset_activated_date__add_field_asset_activation_date.pyc
__init__.py
__init__.pyc
这是south_migrationtable:
id | app_name | migration | applied
----+-----------+-----------------------------------------------------------------------------+-------------------------------
1 | myapp | 0001_initial | 2011-10-14 22:07:11.467184-05
2 | myapp | 0002_auto__add_field_asset_is_reserved__add_field_asset_is_created__add_fie | 2011-10-14 22:07:11.469822-05
3 | myapp | 0003_auto__del_field_asset_is_reserved__add_field_asset_is_assigned | 2011-10-14 22:07:11.471799-05
(3 rows)
这是myapp_asset表,因为它目前为:
Table "public.myapp_asset"
Column | Type | Modifiers
-------------+------------------------+--------------------------------------------------------------
id | integer | not null default nextval('myapp_asset_id_seq'::regclass)
title | character varying(200) |
user_id | integer |
is_assigned | boolean |
is_created | boolean |
is_active | boolean |
Indexes:
"myapp_asset_pkey" PRIMARY KEY, btree (id)
"myapp_asset_user_id" btree (user_id)
Foreign-key constraints:
"myapp_asset_user_id_fkey" FOREIGN KEY (user_id) REFERENCES auth_user(id) DEFERRABLE INITIALLY DEFERRED
我想不通为什么 Django的南认为迁移在0002和0003是“鬼”。它们都位于迁移文件夹中,在迁移表中列为“已应用”,并且数据库似乎与迁移后的最终状态0003一致。
(可能的错误:迁移文件夹包含在git repo;迁移0002创建了一个属性,然后0003重命名了它)
谢谢Yuji。快速提问:在--delete-ghost-migrations中究竟发生了什么? South是否只从south_migrationtable中移除这些行并将其替换为正确的行?我问,因为迁移0002和0003中创建的字段已经填充。 South不会放弃这些数据并重新创建它,是吗? – jchung 2012-01-16 04:56:50
@Jared,不,它只会修改'south_migrationhistory'表。尽管如此,你仍然需要指定'--fake',因为你的db已经反映了这些变化(或者甚至更多 - 但是我无法从你的信息中得知),因为南方在应用“真正”迁移2,3和4时会失败代码示例) – 2012-01-16 05:02:35
更新:问题解决了! Thx – jchung 2012-01-16 21:03:48