こんにちは。sinyです。
この記事では、DjangoのIntegerFieldモデルフィールドの上限値に関する注意点についてのまとめ記事です。
一般的にDjangoで数値型のモデルフィールドを定義する場合はIntegerFieldを使うと思います。
以下のような簡単な製品マスターテーブルを例にして説明します。
class Product(models.Model): class Meta: #カテゴリ verbose_name ="製品マスター" verbose_name_plural ="製品マスター" #カラム名の定義 product_name = models.CharField(max_length=255) jancode = models.IntegerField("janコード")
上記例では、製品を一意に特定するためのカラムjancodeを数値型(IntegerField)で定義しています。
一般的なJanコードは13桁の数値です。
一方、DjangoのIntegerFiledの幅は-2147483648 ~ 2147483647(=MAX10桁)となっています。(下記リンク参照)
ここで疑問なのですが、DjangoのIntegerFiledフィールドの仕様は-2147483648 ~ 2147483647なのに上記モデル定義をマイグレーションしてadmin画面で13桁のjancodeを登録すると普通に登録できてしまいます。
IntegerFieldなのになぜ13桁の数字が登録できてしまうか?の理由がよくわからないので、もしご存知の方がいましたら共有いただけると助かります。
ここで本記事のメインポイントになりますが、別環境DBに登録済みの13桁のjancodeを含むレコードをpython manage.py dumpdataコマンドでjson形式で出力したものを、別のDBにpython manage.py loaddataコマンドでインポートしようとしたところ以下のようなエラーが発生しました。
発生したエラー内容
エラーを見る限り、「integerフィールドの値が範囲外なため登録に失敗している・・・」と言っている模様。
そういえばjancodeってモデルでIntegerFieldを指定していたな・・・
そこで、改めてDjangoモデルフィールドのIntegerField上限値を確認したら2147483647(10桁)だったわけです。
でもadmin画面では13桁の数値で登録できてたよな・・・
仕様と状況が矛盾していてよくわかりませんでしたが、他に悪さしていそうな部分が見当たらなかったため、以下の通りカラムjancodeのデータ型をBigIntegerFieldに変更。
ちなみにBigIntegerFIeldは64 ビットの数値で範囲は-9223372036854775808 ~ 9223372036854775807です。
class Product(models.Model): class Meta: #カテゴリ verbose_name ="製品マスター" verbose_name_plural ="製品マスター" #カラム名の定義 product_name = models.CharField(max_length=255) jancode = models.BigIntegerField("janコード")
その後、python manage.py loaddataコマンドを実行することで、以下のようにエラーなくインポートできるようになりました。
python manage.py loaddata sample.json --app app Installed 92 object(s) from 1 fixture(s)
まとめ
- python manage.py loaddataコマンドで
integerの範囲外エラー が発生した場合はmodels.pyのカラム定義を確認する。 - IntegerFieldを指定していて10桁を超えるデータを登録しようとしていた場合はBigIntegerFieldに変えてみる。
以上、「djangoモデルのIntegerField上限値に関するコラム」でした。