Django field to SQL Server type mappings

この記事では、mssql-djangoバックエンドを使用した場合にDjangoモデルのフィールドタイプがSQL Serverデータ型にどのようにマッピングされるかを記述しています。

フィールドタイプマッピングテーブル

ジャンゴフィールド SQL Server の種類 メモ
AutoField int は IDENTITY(1,1) 主キーの自動増分。
BigAutoField ビジント は IDENTITY(1,1) 64ビットの自動増分主キー。
SmallAutoField smallint は IDENTITY(1,1) 16ビットの自動増分主キー。
BooleanField bit 店舗は 0 か 1。
CharField(max_length=N) nvarchar(N) Unicode文字データ。
DateField date 時間のない日付。
DateTimeField datetime2 日付と時間は分数秒で示します。 USE_TZ=True時にはdatetimeoffsetを使用します。
DecimalField(max_digits=M, decimal_places=D) 数値(M, D) 固定精度の十進法。
DurationField bigint マイクロ秒単位で保存されます。
EmailField ンヴァルチャール(254) CharFieldとメール認証付き。
FileField nvarchar(100) ファイルパスを保存します。
FilePathField nvarchar(100) ファイルシステムのパスを保存します。
FloatField float 64ビット浮動小数点(float(53))。 SQL Serverは同義語double precisionも受け入れています。
IntegerField int 32 ビット符号付き整数。
BigIntegerField bigint 64ビット符号付き整数。
SmallIntegerField smallint 16 ビット符号付き整数。
PositiveIntegerField int CHECK制約 >= 0。
PositiveBigIntegerField bigint CHECK制約 >= 0。
PositiveSmallIntegerField smallint CHECK制約 >= 0。
GenericIPAddressField ヌヴァルチャール(39) IPv4またはIPv6のアドレスです。
JSONField nvarchar(max) JSONチェック制約付きです。 SQL Server 2016+が必要です。
SlugField nvarchar (50) CharFieldとスラッグバリデーション。
TextField nvarchar(max) 無制限の長さのUnicodeテキスト。
TimeField time 日付のない時間。
URLField nvarchar(200) URL検証付きのCharField。
UUIDField char(32) UUIDは32文字の十六進形文字列として格納されます。
BinaryField varbinary(N) 生のバイナリ データ。 バックエンドでは max_length を使って varbinary(N) を発します。
ForeignKey 参照フィールドと同じです インデックスとFK制約を作成します。
OneToOneField 参照フィールドと同じです 一意のインデックスとFK制約を作成します。
ManyToManyField N/A 中間テーブルを作成します。

SQL Server固有の動作

一部のDjangoフィールドタイプは、SQL Serverで使用するとプラットフォーム固有の動作を示します。

オートフィールド制限

移行時にモデルフィールドを AutoField から変更することはサポートされていません。 主キータイプを変更する必要がある場合は、新しいフィールドを作成して手動でデータを移行してください。

BooleanField と bit

SQL Serverビットタイプのストアは0と1です。 Djangoはこれらの値に True/False マッピングします。 NULL BooleanField(null=True)でサポートされています。

DateTimeFieldとタイムゾーンサポート

Djangoの設定でUSE_TZ=Trueすると、DateTimeFieldはdatetimeoffsetを使ってタイムゾーンに対応した日付を保存します。 USE_TZ=False時はdatetime2を使用します。

列を作成後に USE_TZ を有効にする場合は、既存の datetime2 列を 手動でdatetimeoffsetに移行する必要があります。 詳細は mssql-djangoのタイムゾーンサポートをご覧ください。

TextFieldとCharFieldの比較

SQL ServerはナヴァルチャルへのTextFieldとCharFieldの両方をマッピングしています。 TextField nvarchar(max)を使い、CharFieldはnvarchar(N)を使い、Nはmax_lengthです。

すべての文字列フィールドはnvarchar(Unicode)を使用しています。

mssql-djangoバックエンドは、すべてのDjango文字列フィールド(CharField、TextField、EmailField、URLField、SlugFieldなど)をUnicodeの文字列型nvarcharにマッピングします。 varchar(非Unicode)を使うための組み込みオプションはありません。

これは仕様です。 Djangoの文字列処理は全線Unicodeで、 nvarchar は言語やエンコーディングに関係なくすべての文字が正しく格納されることを保証します。 nvarcharを使うことで、文字セットの不一致によるデータ損失を避けられます。

トレードオフ:

  • nvarchar は1文字あたり2バイトを使用しますが、1バイトのコレーションで使う varchar は1文字あたり1バイトです。
  • インデックスキーサイズの制限が適用されます(クラスタ化されていないインデックスは900バイト)。 nvarchar(450)列は900バイト(450×2バイト)の制限に達し、varchar(900)列はシングルバイト文字で同じ制限に達します。
  • もしデータが完全にASCIIであれば、 nvarchar は varcharに比べてストレージ容量が2倍になります。

ヴァルチャールの柱が必要なら:

レガシーデータベースや厳格なストレージ要件がある場合は、以下の db_typeを上書きするカスタムフィールドを作成します。

from django.db import models

class VarcharField(models.CharField):
    def db_type(self, connection):
        return f"varchar({self.max_length})"

class LegacyProduct(models.Model):
    sku = VarcharField(max_length=50)  # Creates varchar(50) instead of nvarchar(50)

    class Meta:
        managed = False  # For existing tables
        db_table = "LegacyProduct"

注意事項

varchar列を使用すると、非ASCII文字が書かれている場合にデータが失われるリスクがあります。 この方法は、そのカラムがASCIIのみのデータを持っていると確信できる場合や、既存のデータベーススキーマとマッチングする必要がある場合のみ使ってください。