Wprowadziłem kilka zmian w moim modelu aplikacji Django i wykorzystałem South do migracji na moim komputerze programistycznym (migracje od 0004 do 0009). Ale podczas próby migracji tych zmian na serwerze pojawia się błąd "GhostMigrations".Co to jest wyjątek Django South GhostMigrations i jak go debugować?
Nie ma zbyt wielu dobrych treści wyjaśniających, czym jest migracja ducha lub jak ją usunąć. Google nie był pomocny w tej sprawie, a pozostałe pytania dotyczące SO, które wspominają o migracji ducha, również tego nie uwzględniają (najbardziej pomocne pytanie dotyczyło głównie przepływu pracy). Pomocni ludzie w IRC django-south mieli to do powiedzenia na temat migracji ducha: "to oznacza historię Południa (tabela w bazie danych) rejestruje dwie migracje, które według niej zostały zastosowane, ale których plików migracji nie może znaleźć" . Próbuję teraz dowiedzieć się, jak zakończyć debugowanie.
Z góry dziękujemy za pomoc.
Oto błąd:
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).
Byłem zaskoczony, aby zobaczyć, że South narzekali migracje 0002 i 0003, ponieważ zrobiłem te zmiany miesięcy temu. Zmiany zrobiłem wcześniej już były zmiany w 0004 przez 0009.
Oto mój model:
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)
Oto zawartość folderu migracje południe:
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
To jest 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)
To myapp_asset tabeli w obecnym brzmieniu:
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
Nie mogę zrozumieć, dlaczego django-południe uważa migracje 0002 i 0003 za "duchy". Oba znajdują się w folderze migracji, są wymienione jako "zastosowane" w tabeli migracji, a baza danych wydaje się być zgodna ze stanem końcowym po migracji 0003.
(Możliwe błędy: folder migracji został uwzględniony w git repo; migracja 0002 utworzyła atrybut, a następnie 0003 zmieniła jego nazwę)
Dzięki Yuji. Szybkie pytanie: co dokładnie dzieje się w migracji - dset-duch? Czy South usuwa te wiersze z south_migrationtable i zastępuje je odpowiednimi wierszami? Pytam, ponieważ pola utworzone w migracji 0002 i 0003 zostały już wypełnione. Południe nie upuści tych danych i nie stworzy ich ponownie, prawda? – jchung
@Jared, nie zmieni to tylko tabeli 'south_migrationhistory'. Nadal będziesz musiał podać '--fake', ponieważ na południu nie uda się zastosować" prawdziwej "migracji 2, 3 i 4, ponieważ twój db już odzwierciedla te zmiany (lub może nawet więcej - ale nie mogę powiedzieć od ciebie sam przykład kodu) –
Aktualizacja: problem rozwiązany! Thx – jchung