2017-01-22 4 views
0

私は、私のdjangoモデルの1つで奇妙な状況に直面しています。 私はPython 3.5.2でDjango 1.10.3を使用しています。フィールドのデフォルト値のバグのためにdjangoの移行が不可能ですか?

モデルは、(明確にするために簡略化)次のようになります。私は./manage.py makemigrationsを使用してジャンゴにより自動生成、モデルを作成し、フィールドを追加し、最初の移行を持っている

class Report(models.Model): 
    date = models.FieldDate() 
    def fieldA_default(self): 
     return MyObject.objects.filter(date=self.date).count() 
    fieldA = models.IntegerField(default=fieldA_default) 

私のgit repoにこのコードをコミットし、それを私のプロダクションサーバーにデプロイしましたが、そのモデルは実際には使用されていません(私のデータベースにはReportのオブジェクトはありません)。 私はこのコードが間違っていることを発見しました(django set default value of a model field to a self attribute)、代わりにsave()を無効にすることを決めました。

fieldA_defaultから0に既定値を変更すると、を実行しようとするため、./manage.py makemigrationsの実行が失敗します。いくつかのオプションを試した後、最終的にモデルを完全に削除することにしました。しかし、makemigrationsはまだ同じ機能を実行しようとしているため、どちらも機能しません。私はいくつかの質問を持っている

Traceback (most recent call last): 
    File "./manage.py", line 22, in <module> 
    execute_from_command_line(sys.argv) 
    File "venv/lib/python3.5/site-packages/django/core/management/__init__.py", line 367, in execute_from_command_line 
    utility.execute() 
    File "venv/lib/python3.5/site-packages/django/core/management/__init__.py", line 359, in execute 
    self.fetch_command(subcommand).run_from_argv(self.argv) 
    File "venv/lib/python3.5/site-packages/django/core/management/base.py", line 294, in run_from_argv 
    self.execute(*args, **cmd_options) 
    File "venv/lib/python3.5/site-packages/django/core/management/base.py", line 345, in execute 
    output = self.handle(*args, **options) 
    File "venv/lib/python3.5/site-packages/django/core/management/commands/makemigrations.py", line 95, in handle 
    loader = MigrationLoader(None, ignore_no_migrations=True) 
    File "venv/lib/python3.5/site-packages/django/db/migrations/loader.py", line 52, in __init__ 
    self.build_graph() 
    File "venv/lib/python3.5/site-packages/django/db/migrations/loader.py", line 197, in build_graph 
    self.load_disk() 
    File "venv/lib/python3.5/site-packages/django/db/migrations/loader.py", line 108, in load_disk 
    migration_module = import_module("%s.%s" % (module_name, migration_name)) 
    File "venv/lib/python3.5/importlib/__init__.py", line 126, in import_module 
    return _bootstrap._gcd_import(name[level:], package, level) 
    File "<frozen importlib._bootstrap>", line 986, in _gcd_import 
    File "<frozen importlib._bootstrap>", line 969, in _find_and_load 
    File "<frozen importlib._bootstrap>", line 958, in _find_and_load_unlocked 
    File "<frozen importlib._bootstrap>", line 673, in _load_unlocked 
    File "<frozen importlib._bootstrap_external>", line 665, in exec_module 
    File "<frozen importlib._bootstrap>", line 222, in _call_with_frames_removed 
    File "xxx/reporting/migrations/0001_initial.py", line 9, in <module> 
    class Migration(migrations.Migration): 
    File "xxx/reporting/migrations/0001_initial.py", line 22, in Migration 
    ('fieldA', models.IntegerField(default=reporting.models.Report.fieldA_default)), 
AttributeError: module 'reporting.models' has no attribute 'Report' 

:ここ

は、私は単にモデルを削除 makemigrationsからトレースバックである理由Djangoは私はしても、この「古い」のコードを実行している

  • モデルを削除しますか?
  • Djangoが私に叫ぶことなく、この無効なコードをマイグレーションにどのように取り込むことができましたか?
  • プロダクションサーバーを壊さないように状況を修正するにはどうすればよいですか?私はモデルを完全に落として再構築しても問題はありませんが、私はそれをすることを許されていないようです。
+0

あなたは、マイグレーションを削除し、 'makemigrations'をもう一度実行して、アプリケーションをゼロに移行しようとしましたか? – schwobaseggl

+0

私はデバッグのための情報が必要です、あなたのdbテーブルdjango_migrationsに行き、あなたのアプリの "0001_initial"の行が存在するかどうか確認してください。これをあなたのポストに追加してください。 – Fian

+0

@schwobasegglあなたの提案がうまくいったようです。私は './manage.pyマイグレーションレポーティングゼロ 'とそれに続く' ./manage.py makemigrations reporting'を実行しましたが、エラーは発生しませんでした。ご協力いただきありがとうございます!これを回答として追加すると、私はそれを受け入れるでしょう:) –

答えて

1

なぜDjangoは、私がモデルを削除していた場合でも、この「古い」のコードを実行していますか?

モデルとそのメソッドがまだ移行ファイルで参照されているので0001_initial.py

しかし、私はfieldA_defaultから0にデフォルトを変更すると、それが実行しようとするため、./manage.py makemigrationsを実行すると失敗します古いデフォルト値関数fieldA_default。

フィールドのデフォルト値をリセットした後で、私は時代遅れのメソッドfieldA_defaultを削除したとします。前述のように、この方法は、初期のマイグレーションで参照されています。

Djangoが私に叫ぶことなく、この無効なコードをマイグレーションにどのように取り込むことができましたか?

移行が作成されたとき、コードは無効ではありませんでした。モデルの一部の変更は、簡単なフォワードマイグレーションでは処理できません。あなたの場合:

  • 同じ(それ自体は単なる非既存のクラスをインポートすることはできませんだけで、他のPythonモジュールである)移行ファイルで参照し、インポートされたときのモデルを削除除去しますデフォルトのメソッド。

    1. python manage.py migrate app_name zero # undo all existing migrations of app

一つのこと、あなたのモデルコードを台無しにされたときに行うことができたり、現在の状態から動作しませんあなたのDB移行/及びmakemigrationsと同期して、次のようです

  • アプリからすべての移行ファイルを削除します。必要に応じて、すでにデシベルで貴重なデータを持っている場合、あなたはそれらを一つ一つを元に戻すことができ、ステップ3は、すでに

  • python manage.py makemigrations app_name # new start from clean sheet

  • を動作するかどうかを確認これは、開発中に簡単ですし、することができマイグレーションの代替手段と見なされていますが、既にdb内に実動データがある場合は最後の手段です。しかし、その場合には、一つは手動:)とにかくケアと配慮して

    0
    1. をモデルの変更を適用
    2. はDBから
    3. 実行のpython manage.pyのmakemigrationsをレポートテーブルを削除し、あなたの移行から報告するすべての参照を削除する必要があります。レポートの新しい移行が作成されます。
    4. プッシュ、展開します。
    関連する問題