前提・実現したいこと
Djangoを勉強中の初心者です。
手習いに、通貨換算を行うアプリケーションを作成しようとしています。
そこで、通貨ペアを保持するモデルを定義したのですが、
どうもUniqueConstraintsを定義するとmigrateを叩いた時にエラーが発生するようです。
constraintsでは、同一の基軸通貨、決済通貨、レート種別に対しては1つのレートのみ登録できるようにしようとしています。
以下に実際のエラーメッセージとソースコードを記載いたしますので、
もし解決方法をご存知の方がいらっしゃれば、是非お知恵をお借りしたく。
発生している問題・エラーメッセージ
Applying myApp.0001_initial...Traceback (most recent call last): File "C:\Users\xxxxx\PycharmProjects\myProject\venv\lib\site-packages\django\db\models\options.py", line 581, in get_field return self.fields_map[field_name] KeyError: 'BASE_CURRENCY' During handling of the above exception, another exception occurred: Traceback (most recent call last): File "manage.py", line 21, in <module> main() File "manage.py", line 17, in main execute_from_command_line(sys.argv) File "C:\Users\xxxxx\PycharmProjects\myProject\venv\lib\site-packages\django\core\management\__init__.py", line 401, in execute_from_command_line utility.execute() File "C:\Users\xxxxx\PycharmProjects\myProject\venv\lib\site-packages\django\core\management\__init__.py", line 395, in execute self.fetch_command(subcommand).run_from_argv(self.argv) File "C:\Users\xxxxx\PycharmProjects\myProject\venv\lib\site-packages\django\core\management\base.py", line 328, in run_from_argv self.execute(*args, **cmd_options) File "C:\Users\xxxxx\PycharmProjects\myProject\venv\lib\site-packages\django\core\management\base.py", line 369, in execute output = self.handle(*args, **options) File "C:\Users\xxxxx\PycharmProjects\myProject\venv\lib\site-packages\django\core\management\base.py", line 83, in wrapped res = handle_func(*args, **kwargs) File "C:\Users\xxxxx\PycharmProjects\myProject\venv\lib\site-packages\django\core\management\commands\migrate.py", line 233, in handle fake_initial=fake_initial, File "C:\Users\xxxxx\PycharmProjects\myProject\venv\lib\site-packages\django\db\migrations\executor.py", line 117, in migrate state = self._migrate_all_forwards(state, plan, full_plan, fake=fake, fake_initial=fake_initial) File "C:\Users\xxxxx\PycharmProjects\myProject\venv\lib\site-packages\django\db\migrations\executor.py", line 147, in _migrate_all_forwards state = self.apply_migration(state, migration, fake=fake, fake_initial=fake_initial) File "C:\Users\xxxxx\PycharmProjects\myProject\venv\lib\site-packages\django\db\migrations\executor.py", line 245, in apply_migration state = migration.apply(state, schema_editor) File "C:\Users\xxxxx\PycharmProjects\myProject\venv\lib\site-packages\django\db\migrations\migration.py", line 124, in apply operation.database_forwards(self.app_label, schema_editor, old_state, project_state) File "C:\Users\xxxxx\PycharmProjects\myProject\venv\lib\site-packages\django\db\migrations\operations\models.py", line 822, in database_forwards schema_editor.add_constraint(model, self.constraint) File "C:\Users\xxxxx\PycharmProjects\myProject\venv\lib\site-packages\django\db\backends\sqlite3\schema.py", line 406, in add_constraint self._remake_table(model) File "C:\Users\xxxxx\PycharmProjects\myProject\venv\lib\site-packages\django\db\backends\sqlite3\schema.py", line 280, in _remake_table self.create_model(new_model) File "C:\Users\xxxxx\PycharmProjects\myProject\venv\lib\site-packages\django\db\backends\base\schema.py", line 322, in create_model sql, params = self.table_sql(model) File "C:\Users\xxxxx\PycharmProjects\myProject\venv\lib\site-packages\django\db\backends\base\schema.py", line 193, in table_sql constraints = [constraint.constraint_sql(model, self) for constraint in model._meta.constraints] File "C:\Users\xxxxx\PycharmProjects\myProject\venv\lib\site-packages\django\db\backends\base\schema.py", line 193, in <listcomp> constraints = [constraint.constraint_sql(model, self) for constraint in model._meta.constraints] File "C:\Users\xxxxx\PycharmProjects\myProject\venv\lib\site-packages\django\db\models\constraints.py", line 89, in constraint_sql fields = [model._meta.get_field(field_name).column for field_name in self.fields] File "C:\Users\xxxxx\PycharmProjects\myProject\venv\lib\site-packages\django\db\models\constraints.py", line 89, in <listcomp> fields = [model._meta.get_field(field_name).column for field_name in self.fields] File "C:\Users\xxxxx\PycharmProjects\myProject\venv\lib\site-packages\django\db\models\options.py", line 583, in get_field raise FieldDoesNotExist("%s has no field named '%s'" % (self.object_name, field_name)) django.core.exceptions.FieldDoesNotExist: NewFxRate has no field named 'BASE_CURRENCY'
該当のソースコード
Python
1from django.db import models 2 3 4class FxRate(models.Model): 5 """ 6 為替レート(基軸通貨/決済通貨) 7 """ 8 9 objects = models.Manager() 10 11 # id = AutoField(primary_key=True) # 自動的に追加されるため定義不要 12 13 base_currency = models.CharField( 14 verbose_name="基軸通貨", name="Base Currency", 15 blank=False, null=False, max_length=3, 16 db_column="BASE_CURRENCY" 17 ) 18 19 quote_currency = models.CharField( 20 verbose_name="決済通貨", name="Quote Currency", 21 blank=False, null=False, max_length=3, 22 db_column="QUOTE_CURRENCY" 23 ) 24 25 rate_type = models.CharField( 26 verbose_name="レート種別", name="Rate Type", 27 blank=False, null=False, max_length=3, 28 db_column="RATE_TYPE" 29 ) 30 31 rate = models.DecimalField( 32 verbose_name="為替レート", name="FX Rate", 33 blank=False, null=False, decimal_places=2, max_digits=6, 34 db_column="FX_RATE" 35 ) 36 37 class Meta: 38 db_table = "FX_RATE" 39 constraints = [ 40 models.UniqueConstraint( 41 fields=['BASE_CURRENCY', 'QUOTE_CURRENCY', 'RATE_TYPE'], 42 name='FX_RATE_CURRENCIES_AND_RATE_TYPE_UNIQUE' 43 ) 44 ]
試したこと
- constraintsを削除
-> 正常にmigrateが動作することを確認しました。
- fieldsに指定する名前をUpperCaseとLowerCaseで試行
-> fieldsに指定するのが変数名なのかdb_columnで定義した名前なのかが判別できなかったため、UpperCaseもLowerCaseも試しましたがどちらも同様のエラーが発生。
エラーメッセージから色々と検索をかけ、ForeignKeyをfieldsに含めると同様のエラーが発生する場合は見つけました。
しかし、今回は自モデルのみに閉じた定義を行っているはずなので、該当せず。
また、「FieldDoesNotExist: NewFxRate」と、何故かクラス名が「New」になっている点も理解できず。
全てDjangoからアクセスかける場合は独自にバリデーションメソッドを作成すれば良いので回避策はあるのですが、
Django公式にて推奨されているUniqueConstraintsが利用できない、というのは気持ちが悪いため、出来れば解決したいと思っています。
補足情報(FW/ツールのバージョンなど)
・Windows10(64bit)
・Anaconda3(2020.02) = Python3.7
・PyCharm(Community)
・VirtualEnv(venv)
・sqlite3
回答2件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2020/06/10 01:11