ValueError: Related model ” cannot be resolved

クライアント環境で新たに追加したテーブルを既存テーブルの項目として外部キーを指定して追加した後、デプロイ先のクラウド環境へ同様の作業を行おうとして、躓いたので備忘録。
新たに追加したテーブルを既存のテーブルの項目として追加し、外部キーとして追加した。
作業手順としては、
・新しいテーブルを作成
・新しいテーブルにデータを追加
・既存テーブルの項目に新しいテーブルの外部キーを追加
ところが、デプロイ先ではこの手順で作業しようとすると、
>python manage.py makemigrations
を実行した時点で、
ValueError: The field [既存テーブルの項目名] was declared with a lazy reference to ‘[アプリ名.追加テーブル名]’, but app ‘[アプリ名]’ doesn’t provide model ‘追加テーブル名’.
と怒られた。
そこで、どうやら、手で追加したテーブルがmigrationとして認識されていないなと思い、手作業で追加したテーブルをdropして、magrationsフォルダの下の最新のmigration実行用ファイル(000n_auto_YYYYMMDD-HHFF.py)の追加したテーブル部分だけを残してそのほかを削除し、
>python manage.py migrate
を実行して、データを管理画面から手で追加。
再度、最新のファイルの内容を既存テーブルの項目(migrations.Addfield(…))だけ残して実行すると、今度は
ValueError: Related model ‘[アプリ名.追加テーブル名]’ cannot be resolved
と怒られた。
結論から言うと、migration実行用ファイル(000n_auto_YYYYMMDD-HHFF.py)内の
dependencies = [
(‘[アプリ名]’, ‘000n_auto_YYYYMMDD_HHFF’),
]
のアンダーライン部分をそのまま実行したため、migration処理が直前の処理を認識できず、エラーを吐いていたと思われる。
新たにmigration実行用ファイルを追加して、そこに既存テーブルへの外部キーを追加する処理部分を記載し、dependenciesに先ほどテーブル作成したファイル名(.pyを除く)を指定して
>python manage.py migrate
を実行したら、無事作成できた。
当然と言えば、当然だけれど、エラーだけ見るとさっぱりわからないし、ググっても同じような事例は見当たらなかった。
わかったことは、migrationという仕組みが、実テーブルだけではなく、前回実行履歴を参照して実行されるということと、外部キー参照している項目を追加する場合、元のテーブルは作成しているだけではなく、実データも入力していないと、外部キーとして項目追加するとき、デフォルト設定した値の参照先がないというエラーとなり、migrateできなくなる。
この場合は、上記のように、最初に参照先のテーブルを作成するようmigration実行用ファイルを修正して、migarateし、データをinsert後、外部キーの項目追加をおこなう必要がある。
その時参照される履歴とは、[アプリ名]’, ‘000n_auto_YYYYMMDD_HHFF.pyであり、000n_auto_YYYYMMDD_HHFF.cpython-99.pycということだ。
このことを知っていれば、同エラーが発生した場合、全テーブルをdropして、maigarationsフォルダ配下のファイルを__init__.py以外すべて削除して再度作成しなおしたらうまくいったなどという解決策を平然とのせている回答例よりはましな解決策がみつかるのではないか?

コメントする