Что такое исключение Django South GhostMigrations и как вы его отлаживаете? - PullRequest
23 голосов
/ 16 января 2012

Внесены некоторые изменения в модель моего приложения Django и использованы South для переноса их на мою машину разработки (миграция с 0004 по 0009).Но при попытке перенести эти изменения на сервер я получаю сообщение об ошибке «GhostMigrations».

Не так много хорошего материала, объясняющего, что такое миграция привидений или как ее отладить.Google не помог в этом вопросе, а другие вопросы SO, в которых упоминается миграция призраков, также не охватывают этот вопрос (самый полезный вопрос здесь касался главным образом рабочего процесса).Полезные люди из IRC django-south сказали следующее о миграции призраков: «это означает, что история юга (таблица в БД) записывает две миграции, которые, по его мнению, были применены, но чьи файлы миграции он не может найти»,Сейчас я пытаюсь понять, как завершить отладку.

Заранее спасибо за помощь.

Вот ошибка:

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-south считает миграции 0002 и 0003 "призраками".Они оба находятся в папке миграции, перечислены как «примененные» в таблице миграции, и база данных, кажется, соответствует конечному состоянию после миграции 0003.

(возможные ошибки: папка миграции была включенав git repo; миграция 0002 создала атрибут, а затем 0003 переименовала его)

Ответы [ 2 ]

23 голосов
/ 16 января 2012

Каким-то образом в вашей базе данных записаны миграции 0002 и 0003, которые не могут быть найдены в папке миграций.

Миграция 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+.

Вы бы лучше знали, какая миграция текущей таблицы БД должна совпадать!

7 голосов
/ 16 января 2012

Они считаются призрачными миграциями, потому что имена в базе данных:

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 к южной таблице БД, а затем обновить две строки, чтобы числа соответствовали вашей имена файлов.

Само собой разумеется, что вы должны сделать резервную копию всего, прежде чем делать это.

...