2012-01-16 26 views
23

Thực hiện một số thay đổi đối với mô hình ứng dụng Django của tôi và sử dụng Nam để di chuyển chúng trên máy phát triển của tôi (di chuyển 0004 đến 0009). Nhưng khi cố gắng di chuyển những thay đổi này trên máy chủ, tôi nhận được lỗi "GhostMigrations".Ngoại lệ GhostMigrations Django Nam là gì và bạn gỡ lỗi như thế nào?

Không có nhiều nội dung hay giải thích về việc di chuyển ma là gì hoặc cách gỡ lỗi. Google không hữu ích về vấn đề này và các câu hỏi SO khác đề cập đến việc di chuyển ma không bao gồm vấn đề này (câu hỏi hữu ích nhất here chủ yếu là về quy trình làm việc). Các folks hữu ích hơn trong IRC django-nam có điều này để nói về di cư ma: "nó có nghĩa là lịch sử của nam (một bảng trong db) ghi lại hai di cư mà nó nghĩ đã được áp dụng, nhưng các tập tin di chuyển nó không thể tìm thấy" . Tôi đang cố gắng tìm ra ngay bây giờ làm thế nào để hoàn thành việc gỡ lỗi.

Cảm ơn bạn đã trợ giúp.

Dưới đây là các lỗi:

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

Tôi rất ngạc nhiên khi thấy rằng Nam phàn nàn về cuộc di cư 0002 và 0003, vì tôi đã thực hiện những thay đổi đó vài tháng trước đây. Những thay đổi tôi thực hiện sớm hôm nay là thay đổi 0004 qua 0009

Dưới đây là mô hình của tôi:

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) 

Dưới đây là nội dung của thư mục di cư về phía nam:

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 

này là 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) 

Đây là bảng myapp_asset vì nó hiện đang đứng:

        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 

Tôi không thể hiểu tại sao django-nam coi di cư 0002 và 0003 là "ma". Cả hai đều nằm trong thư mục di chuyển, được liệt kê là "được áp dụng" trong migrationtable và cơ sở dữ liệu có vẻ phù hợp với trạng thái kết thúc sau khi di chuyển 0003.

(có thể có lỗi: thư mục di chuyển được bao gồm trong git repo; di chuyển 0002 đã tạo một thuộc tính, và sau đó 0003 đổi tên nó)

Trả lời

23

Bằng cách nào đó, cơ sở dữ liệu của bạn đã ghi lại di chuyển 0002 và 0003 mà nó không thể tìm thấy trong thư mục di chuyển của bạn.

Migration 0002 trong hệ thống tập tin của bạn là 0002_auto__chg_field_asset_username__chg_field_asset_title__chg_field_asset.py trong khi ở trong bảng lịch sử đó là 0002_auto__add_field_asset_is_reserved__add_field_asset_is_created__add_fie.py

Nam phải được di chuyển khi thư mục di cư của bạn có nội dung khác nhau (có lẽ trong sự phát triển?).

Dựa trên những gì bạn đang nói, có vẻ như tôi giống như cơ sở dữ liệu của bạn phản ánh trạng thái di chuyển 0004, vì vậy tôi sẽ chạy python manage.py migrate myapp 0004 --fake --delete-ghost-migrations để đặt bảng di chuyển tại thời điểm bạn thêm trường is_assigned và bạn có thể áp dụng hạnh phúc di cư 0005+.

Bạn muốn biết di chuyển nào tốt nhất bảng DB hiện tại nên phù hợp!

+0

Cảm ơn Yuji. Câu hỏi nhanh: những gì chính xác xảy ra trong một - di chuyển ma-di chuyển? Miền Nam có xóa các hàng từ south_migrationtable và thay thế chúng bằng các hàng chính xác không? Tôi hỏi vì các trường được tạo trong di chuyển 0002 và 0003 đã được phổ biến. Nam sẽ không bỏ dữ liệu đó và tái tạo nó, phải không? – jchung

+1

@Jared, không có nó sẽ chỉ sửa đổi bảng 'south_migrationhistory'. Bạn vẫn sẽ cần phải xác định '--fake' mặc dù vì miền nam sẽ thất bại khi áp dụng di chuyển" thực "" 2, 3 và 4 làm db của bạn đã phản ánh những thay đổi đó (hoặc thậm chí nhiều hơn - nhưng tôi không thể nói từ mã mẫu một mình) –

+0

Cập nhật: vấn đề được giải quyết! Thx – jchung

7

Họ được coi là di cư ma vì các tên trong cơ sở dữ liệu:

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 

không phù hợp với tên tập tin bạn liệt kê:

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 

Các con số là một phần của tên tập tin và phải phù hợp một cách hoàn hảo . Tôi không chắc làm thế nào bạn đạt đến trạng thái này, nhưng nếu bạn hoàn toàn chắc chắn rằng DB của bạn khớp với những gì có trong tệp 0004 của bạn, bạn có thể thêm 0002_auto__chg_field_asset_username__chg_field_asset_title__chg_field_asset vào bảng DB phía nam, sau đó cập nhật hai hàng để các số khớp với tên tệp của bạn.

Không cần phải nói bạn nên sao lưu mọi thứ trước khi thực hiện việc này.

+0

Dường như lần di chuyển đầu tiên (0001initial) bao gồm cả di chuyển 0001 và 0002 như được mô tả trong thư mục di chuyển. Điều đó sẽ giải thích tại sao các số di chuyển không đồng bộ. Rõ ràng là một lỗi trong quy trình làm việc của tôi. Vì vậy, nếu tôi chỉ sửa chữa các hàng trong cơ sở dữ liệu, điều đó sẽ đưa miền Nam trở lại đồng bộ, đúng không? Sau đó, sau khi sửa chữa, tôi sẽ chạy "di chuyển" một lần nữa để có Nam di chuyển về phía trước để di chuyển 0009 (đó là nơi tôi đang cố gắng để có được)? – jchung

+0

Có, hoặc 'di chuyển myapp --fake' di chuyển đến điểm bạn biết cơ sở dữ liệu của bạn hiện đang đại diện và xóa di chuyển ma bằng đối số' --delete-ghost-migrations'. –

+0

Cập nhật: sự cố được giải quyết! Cám ơn – jchung

Các vấn đề liên quan