Django field 到 SQL Server 類型映射

本文說明了 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 資料,或需要匹配現有資料庫結構時才使用這種方法。