本文說明了 Django 模型欄位類型在使用mssql-django後端時如何映射到 SQL Server 資料型別。
欄位類型映射表
| Django 場 | SQL Server 類型 | Notes |
|---|---|---|
AutoField |
智力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 | 日期和時間,並以分秒表示。 當 時使用 datetimeoffset。USE_TZ=True |
DecimalField(max_digits=M, decimal_places=D) |
數字(M, D) | 固定精度十進位。 |
DurationField |
bigint | 以微秒級儲存。 |
EmailField |
恩瓦爾查爾(254) | CharField 搭配電子郵件驗證功能。 |
FileField |
nvarchar(100) | 儲存檔案路徑。 |
FilePathField |
nvarchar(100) | 儲存檔案系統路徑。 |
FloatField |
float | 64 位元浮點數(float(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 檢查約束。 |
SlugField |
nvarchar(50) | 帶有 slug 驗證的 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 限制
在遷移時不支援將模型欄位從 或 改為 。AutoField 如果需要更改主鍵類型,請建立新欄位並手動遷移資料。
布林場與位元
SQL Server 位元類型儲存 0 和 1。 Django 會映射 True/False 到這些值。
NULL 以 為 支持 BooleanField(null=True)。
DateTimeField 與時區支援
在 Django 設定中 USE_TZ=True ,使用 DateTimeFielddatetimeoffset 來儲存時區感知日期時間。 當 USE_TZ=False時,則使用 datetime2。
如果你是在建立欄位後啟用 USE_TZ ,必須手動將現有 的 datetime2 欄位遷移到 datetimeoffset。 更多資訊請參閱 mssql-django 中的時區支援。
TextField 與 CharField 比較
SQL Server 會將兩者 TextField 和 CharField 映射到 nvarchar。
TextField 使用 nvarchar(max), 而 CharField 使用 nvarchar(N), 其中 N 為 max_length。
所有字串欄位皆使用 nvarchar(Unicode)
後端會mssql-django將所有 Django 字串欄位(CharField、、TextFieldEmailFieldURLFieldSlugField、、及其他欄位)映射到 Unicode 字串類型 nvarchar。 沒有內建選項可以直接使用 varchar (非 Unicode)。
這是原廠設定。 Django 的字串處理全程採用 Unicode,nvarchar 確保所有字元無論語言或編碼方式皆正確儲存。 使用 nvarchar 可以避免因字元集不匹配而遺失資料。
取捨:
- nvarchar 每個字元使用 2 位元組,而 varchar 則以單位元組彙整為每個字元1位元組。
- 索引鍵大小限制適用(非叢集索引為 900 位元組)。 nvarchar(450) 欄位達到 900 位元組限制(450 x 2 位元組),而 varchar(900) 欄位則使用單字元時達到相同限制。
- 如果你的資料完全是 ASCII,nvarchar 的儲存容量是 varchar 的兩倍。
如果你需要 varchar 柱:
對於舊有資料庫或嚴格的儲存需求,請建立一個自訂欄位覆蓋: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 資料,或需要匹配現有資料庫結構時才使用這種方法。