什么是Django South GhostMigrations异常,如何调试它? [英] What is a Django South GhostMigrations exception and how do you debug it?

查看:68
本文介绍了什么是Django South GhostMigrations异常,如何调试它?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

对我的Django应用程序的模型进行了一些更改,并使用South将其迁移到我的开发计算机上(迁移0004到0009)。但是,当尝试在服务器上迁移这些更改时,出现 GhostMigrations错误。

Made some changes to my Django app's model and used South to migrate them on my development machine (migrations 0004 through 0009). But when trying to migrate these changes on the server, I get a "GhostMigrations" error.

没有什么好的内容可以解释什么是幻影迁移或如何调试。 Google对此无济于事,而其他提到幽灵迁移的问题也没有解决(最有用的问题此处主要是关于工作流程的)。在django-south IRC中,乐于助人的人们对幽灵迁移有这样的说法:这意味着South的历史记录(数据库中的一个表)记录了它认为已应用的两个迁移,但是找不到其迁移文件 。我正在尝试弄清楚如何完成调试。

There isn't much good content explaining what a ghost migration is, or how to debug one. Google wasn't helpful on this one and the other SO questions mentioning ghost migrations don't cover this either (the most helpful question here was mostly about workflow). The helpful folks over in the django-south IRC had this to say about ghost migrations: "it means south's history (a table in the db) records two migrations that it thinks have been applied, but whose migration files it can't find". I'm trying to figure out now how to complete the debug.

在此先感谢您的帮助。

Thanks in advance for the help.

这是错误:

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。

I was surprised to see that South complained about migrations 0002 and 0003, because I made those changes months ago. The changes I made earlier today were changes 0004 through 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_migration表:

 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是幽灵。两者都在migrations文件夹中,在migrationtable中列为已应用,并且数据库在迁移0003之后似乎与最终状态一致。

I can't figure out why django-south considers migrations 0002 and 0003 to be "Ghosts". Both of them are in the migrations folder, are listed as "applied" in the migrationtable, and the database seems to be consistent with the end-state after migration 0003.

(可能的错误:迁移文件夹包含在git repo中;迁移0002创建了一个属性,然后将其重命名为0003)

(possible errors: the migrations folder was included in the git repo; migration 0002 created an attribute, and then 0003 renamed it)

推荐答案

以某种方式,您的数据库记录了迁移0002和0003,这些在迁移文件夹中找不到。

Somehow, your database has recorded migrations 0002 and 0003 which it can't find in your migrations folder.

文件系统中的迁移 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

Migration 0002 in your filesystem is 0002_auto__chg_field_asset_username__chg_field_asset_title__chg_field_asset.py while the in in the history table it's 0002_auto__add_field_asset_is_reserved__add_field_asset_is_created__add_fie.py

必须在迁移文件夹不同的情况下进行迁移内容(也许正在开发中?)。

South must have been migrated when your migrations folder had different contents (perhaps in development?).

根据您的意思,我觉得您的数据库反映了迁移状态 0004 ,所以我要运行 python manage.py migration myapp 0004 --fake --delete-ghost-migrations ,它将设置迁移表此时,您添加了 is_assigned 字段,您可以愉快地应用迁移 0005 +

Based on what you're saying, it looks to me like your database reflects the state at migration 0004, so I'd run a python manage.py migrate myapp 0004 --fake --delete-ghost-migrations which will set the migration table at the point you added the is_assigned field, and you can happily apply migrations 0005+.

您将最清楚地知道当前数据库表应该匹配哪个迁移!

You'd know best which migration the current DB table should match though!

这篇关于什么是Django South GhostMigrations异常,如何调试它?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆