この記事では、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のみのデータを持っていると確信できる場合や、既存のデータベーススキーマとマッチングする必要がある場合のみ使ってください。