2015-12-10 4 views
11

の問題を解決しました。テーブルの名前変更を含むDjango(1.8.7)移行を元に戻しました。 Postgresで名前を変更できるように見えても、の古いテーブル名を使用して制約を追加しようとします。あなたは、そのテーブルにはないにもかかわらず、team_membershiproleへの参照があることを見ることができますが、それが生成SQLを見てみる場合は、Djangoで表の名前を変更するために自動生成された移行を復帰するときのエラー

cursor.execute(sql, params) 
    File "/Users/myworkspace/projects/xxx/venv/lib/python3.5/site-packages/django/db/backends/utils.py", line 79, in execute 
    return super(CursorDebugWrapper, self).execute(sql, params) 
    File "/Users/myworkspace/projects/xxx/venv/lib/python3.5/site-packages/django/db/backends/utils.py", line 64, in execute 
    return self.cursor.execute(sql, params) 
    File "/Users/myworkspace/projects/xxx/venv/lib/python3.5/site-packages/django/db/utils.py", line 97, in __exit__ 
    six.reraise(dj_exc_type, dj_exc_value, traceback) 
    File "/Users/myworkspace/projects/xxx/venv/lib/python3.5/site-packages/django/utils/six.py", line 658, in reraise 
    raise value.with_traceback(tb) 
    File "/Users/myworkspace/projects/xxx/venv/lib/python3.5/site-packages/django/db/backends/utils.py", line 64, in execute 
    return self.cursor.execute(sql, params) 
django.db.utils.ProgrammingError: relation "team_membershiprole" does not exist 

[...] 
ALTER TABLE "team_membershiprole" RENAME TO "team_leadershiprole"; 
[...] 
ALTER TABLE "team_leadershipteammember" 
    ADD CONSTRAINT "team_l_role_id_xxx" 
    FOREIGN KEY ("role_id") REFERENCES "team_membershiprole" ("id")  
    DEFERRABLE INITIALLY DEFERRED; 
[...] 

COMMIT; 

:ここ

は、トレースバックですもう存在しない(名前が変更された)。ここでは、移行コードがあります:

# -*- coding: utf-8 -*- 
from __future__ import unicode_literals 

from django.db import models, migrations 


class Migration(migrations.Migration): 

    dependencies = [ 
     ('core', '0023_xxx'), 
     ('team', '0009_xxx2'), 
    ] 

    operations = [ 
     migrations.CreateModel(
      name='TeamMembership', 
      fields=[ 
       ('id', models.AutoField(serialize=False, auto_created=True, verbose_name='ID', primary_key=True)), 
       ('team', models.ForeignKey(related_name='members', to='team.Team')), 
       ('member', models.ForeignKey(to='core.Member')), 
      ], 
     ), 
     migrations.RenameModel(
      old_name='LeadershipRole', 
      new_name='MembershipRole', 
     ), 
     migrations.RemoveField(
      model_name='leadershipteammember', 
      name='team', 
     ), 
     migrations.RemoveField(
      model_name='leadershipteammember', 
      name='member', 
     ), 
     migrations.RemoveField(
      model_name='leadershipteammember', 
      name='role', 
     ), 
     migrations.DeleteModel(
      name='LeadershipTeamMember', 
     ), 
     migrations.AddField(
      model_name='teammembership', 
      name='role', 
      field=models.ForeignKey(to='team.MembershipRole'), 
     ), 
    ] 

私はこのことを理解しているDjangoの移行のバグが、それを回避する方法はありますでしょうか?

+1

1.9で動作するかどうかを確認し、そうでない場合はhttps://code.djangoproject.com/newticketでチケットを作成できますか?根本的な原因を特定し、回避策を開発するのにも役立ちます。 – knbk

+0

私はそれを試し、ここで結果をコメントします。 –

答えて

1

Migration.unapplyをオーバーライドして、異なる操作セットを使用することができます。

class MyMigration(Migration): 
    operations = [ 
     ... your operations ... 
    ] 
    reverse_operations = [ 
     ... your fixed reverse operations ... 
    ] 
    def unapply(self, project_state, schema_editor, collect_sql=False): 
     self.operations = self.reverse_operations 
     return super(MyMigration, self).unapply(..) 

これはテストしていませんが、わかりやすいものです。ああ、逆方向の移行のリストを逆にする必要があるかもしれません。なぜなら、Djangoはそれを順方向の移行のリストにすることを期待しているからです。

+0

それは理にかなっていますが、逆の移行のための生のSQLクエリを追加すべきですか?私は少なくとも操作のためにDjangoのマイグレーションAPIを使い続けたいと思います。 –

+0

Ok()を呼び出す前に、Migration.unapplyをオーバーライドして、カスタマイズされたself.operationsを適切な場所にハックすることができるように見えるソースを確認してください。私はこれが最善だと思います、私は最初に提案したRunPythonのものは必要ありません。 –

関連する問題