web-dev-qa-db-ja.com

Django South GhostMigrations例外とは何ですか?どのようにデバッグしますか?

Djangoアプリのモデルにいくつかの変更を加え、Southを使用して開発マシンに移行しました(移行0004から0009)。しかし、サーバーでこれらの変更を移行しようとすると、「GhostMigrations」が表示されます。 「エラー。

ゴースト移行とは何か、またはゴースト移行をデバッグする方法を説明する良いコンテンツはあまりありません。 Googleはこれについては役に立ちませんでしたが、他のSOゴースト移行について言及している質問もこれをカバーしていません(最も役立つ質問 ここ は主にワークフローに関するものでした)。 Django-south IRC)の親切な人々は、ゴーストの移行について次のように述べています。移行ファイルが見つかりません」。デバッグを完了する方法を理解しようとしています。

助けてくれてありがとう。

エラーは次のとおりです:

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

数か月前に変更を加えたため、Southが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)

これがsouthmigrationsフォルダーの内容です:

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-southは移行0002と0003を「ゴースト」と見なします。どちらも移行フォルダにあり、移行テーブルに「適用済み」としてリストされており、データベースは移行後の最終状態と一致しているようです0003。

(エラーの可能性:移行フォルダーがgitリポジトリに含まれていました。移行0002が属性を作成し、0003の名前が変更されました)

23
jchung

どういうわけか、データベースに移行0002と0003が記録されていますが、移行フォルダにはありません。

ファイルシステムの移行00020002_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です。

移行フォルダの内容が異なる場合(おそらく開発中ですか?)、Southは移行されている必要があります。

あなたの言っていることに基づいて、あなたのデータベースは移行時の状態を反映しているように見えます0004なので、python manage.py migrate myapp 0004 --fake --delete-ghost-migrationsフィールドを追加した時点で移行テーブルを設定するis_assignedを実行すると、移行を喜んで適用できます0005+

現在のDBテーブルがどの移行に一致するかを最もよく知っているでしょうすべきですしかし!

24

データベース内の名前が次の理由から、これらはゴースト移行と見なされます。

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

番号はファイル名の一部であり、完全に一致する必要があります。どのようにしてこの状態に到達したかはわかりませんが、DBが0004ファイルにあるものと完全に一致することが確実な場合は、南のDBテーブルに0002_auto__chg_field_asset_username__chg_field_asset_title__chg_field_assetを追加してから、2つの行を更新して数値を更新できます。ファイル名と一致します。

言うまでもなく、これを行う前にすべてをバックアップする必要があります。

7
dgel