Djangoで新規にテーブルを作成したのでマイグレーションを実行したところ、以下のようなエラーが発生しました。開発中には発生せず、リポジトリにコミットしたものをチェックアウトした場合に発生しました。
$ python manage.py makemigrations
Traceback (most recent call last):
File "/usr/local/lib/python3.12/site-packages/django/db/backends/utils.py", line 105, in _execute
return self.cursor.execute(sql, params)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/local/lib/python3.12/site-packages/psycopg/cursor.py", line 732, in execute
raise ex.with_traceback(None)
psycopg.errors.UndefinedTable: relation "system_parameter" does not exist
LINE 1: ..."system_parameter"."maximum_value2" FROM "system_...
^
The above exception was the direct cause of the following exception:
画面に出力されたエラーを確認するとsystem_parameterテーブルがないことが原因らしいことがわかりました。
system_parameterを使うためにマイグレーションしてるのだからテーブルがないのは当然なのに存在しないからマイグレーションできないのは納得できず、さらに下を見ていくと中盤でマイグレーションとは無関係なはずの自分が改修したプログラムが実行されていました。
File "<frozen importlib._bootstrap_external>", line 995, in exec_module
File "<frozen importlib._bootstrap>", line 488, in _call_with_frames_removed
File "/var/www/venv/webApp/accounts/urls.py", line 4, in <module>
from . import views
File "/var/www/venv/webApp/accounts/views.py", line 593, in <module>
class AccountListView(ListView):
File "/var/www/venv/webApp/accounts/views.py", line 594, in AccountListView
paginate_by = sys_param.get_value(sys_param.ACCOUNT_OF_ROWS_PER_PAGE)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/var/www/venv/webApp/app/utils/sys_param.py", line 178, in get_value
if not stored_cache():
^^^^^^^^^^^^^^
File "/var/www/venv/webApp/app/utils/sys_param.py", line 112, in stored_cache
for rec in system_parameter:
File "/usr/local/lib/python3.12/site-packages/django/db/models/query.py", line 400, in __iter__
self._fetch_all()
File "/usr/local/lib/python3.12/site-packages/django/db/models/query.py", line 1928, in _fetch_all
self._result_cache = list(self._iterable_class(self))
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
追加したsystem_parameterを参照するコードをなぜか実行されていて、マイグレーションが終わっていないのでテーブル参照したらエラーになるのは当たり前。コレが直接の原因でした。
マイグレーションで自分が作ったコードをなぜ実行されるのか原因がわからないのですが、とりあえずテーブルが作成されるまではテーブルを参照しないように以下のコードを追加しました。
# マイグレーション時対応
# テーブルが作成されていない場合、処理を中断する。
if not 'system_parameter' in connection.introspection.table_names():
logger.debug('テーブルが存在していません。[system_parameter]')
return False
本当の原因を突き止めて恒久対応にしたかったんですけど、時間がかかりそうなのとプロジェクトを離れることが決まっていましたので、残ったメンバーに託します。
ちなみに今回の件は開発中にわからなかったのかっていうとわかりませんでした。
マイグレーション時に問題となったコードがあったために発生したので、開発のようにマイグレーションが終わってコードをつくるという状況では発生しません。
今後はマイグレーションが必要な場合、コードありきのマイグレーションの実施を考慮することにします。
【開発環境】
OS:Windows 11
Docker: 26.0
Python: 3.11
Django: 4.2