質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Django

DjangoはPythonで書かれた、オープンソースウェブアプリケーションのフレームワークです。複雑なデータベースを扱うウェブサイトを開発する際に必要な労力を減らす為にデザインされました。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Q&A

解決済

2回答

945閲覧

Djangoのモデル定義のUniqueConstraintsを使用するとFieldDoesNotExistが発生する

Jin.Keika

総合スコア0

Django

DjangoはPythonで書かれた、オープンソースウェブアプリケーションのフレームワークです。複雑なデータベースを扱うウェブサイトを開発する際に必要な労力を減らす為にデザインされました。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

0グッド

0クリップ

投稿2020/06/08 09:50

前提・実現したいこと

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 ]

試したこと

  1. constraintsを削除

-> 正常にmigrateが動作することを確認しました。

  1. 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

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

fieldsに指定する名前をUpperCaseとLowerCaseで試行

UniqueConstraintfieldsには、base_currencyなどフィールド名を指定する必要があります。

投稿2020/06/09 23:23

hasami

総合スコア1277

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Jin.Keika

2020/06/10 01:11

「フィールド名」とのコメントをいただいたことで解決方法がわかりました。 ありがとうございました!
guest

0

自己解決

解決しました。

filedOptionで誤ったnameを指定していたことが問題でした。
verbose_name同様、属性としての名前(英名)を指定するオプションだと勘違いしていましたが、field名を書き換えるためのオプションでした。

nameオプションをすべて削除し、改めてLowerCaseのfield名を指定してUniqueConstraintsを定義したらmigrationが通りました。

ありがとうございました。

投稿2020/06/10 01:09

Jin.Keika

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問