對我的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