2012-01-16 33 views
23

對我的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重命名了它)

回答

23

不知何故,您的數據庫已記錄migrations 0002和0003,它無法在您的migrations文件夾中找到。

遷移0002在你的文件系統是0002_auto__chg_field_asset_username__chg_field_asset_title__chg_field_asset.py,而在歷史記錄表中,在它的0002_auto__add_field_asset_is_reserved__add_field_asset_is_created__add_fie.py

南必須在遷移過程的文件夾有不同的內容已被遷移(可能發展?)。

基於你在說什麼,它看起來對我來說,你的數據庫反映遷移0004的狀態,所以我會運行一個python manage.py migrate myapp 0004 --fake --delete-ghost-migrations將設置遷移表在您添加的is_assigned場點,和你可以愉快地申請遷移0005+

你最好知道哪個遷移當前DB表應該匹配!

+0

謝謝Yuji。快速提問:在--delete-ghost-migrations中究竟發生了什麼? South是否只從south_migrationtable中移除這些行並將其替換爲正確的行?我問,因爲遷移0002和0003中創建的字段已經填充。 South不會放棄這些數據並重新創建它,是嗎? – jchung 2012-01-16 04:56:50

+1

@Jared,不,它只會修改'south_migrationhistory'表。儘管如此,你仍然需要指定'--fake',因爲你的db已經反映了這些變化(或者甚至更多 - 但是我無法從你的信息中得知),因爲南方在應用「真正」遷移2,3和4時會失敗代碼示例) – 2012-01-16 05:02:35

+0

更新:問題解決了! Thx – jchung 2012-01-16 21:03:48

7

它們被認爲是鬼遷移,因爲在數據庫中的名稱:

0002_auto__add_field_asset_is_reserved__add_field_asset_is_created__add_fie 
0003_auto__del_field_asset_is_reserved__add_field_asset_is_assigned 

不匹配你列出的文件名:

0003_auto__add_field_asset_is_reserved__add_field_asset_is_created__add_fie.py 
0004_auto__del_field_asset_is_reserved__add_field_asset_is_assigned.py 

的數字是文件名的一部分,必須完全匹配。我不確定你是如何到達這個狀態的,但是如果你確定你的數據庫與你的0004文件中的內容相匹配,你可以在南數據庫表中添加0002_auto__chg_field_asset_username__chg_field_asset_title__chg_field_asset,然後更新這兩行,使得這些數字與你的文件名匹配。

不用說,在做這件事之前你應該支持所有事情。

+0

看起來像遷移文件夾中所述,第一次遷移(0001initial)包括遷移0001和0002。這將解釋爲什麼遷移數字不同步。很明顯,在我的工作流程中出現錯誤因此,如果我只修復數據庫中的行,這將使南方恢復同步,對吧?然後,在做出修復之後,我會再次運行「遷移」以讓南遷移至遷移0009(這正是我試圖獲得的目標)嗎? – jchung 2012-01-16 04:41:32

+0

是,或者「遷移myapp --fake」,遷移到您知道您的數據庫當前使用'--delete-ghost-migrations'參數表示並刪除ghost遷移的點。 – 2012-01-16 04:48:40

+0

更新:問題解決了!謝謝 – jchung 2012-01-16 21:04:11

相關問題