Django-fält-till-SQL Server-typmappningar

Denna artikel dokumenterar hur Django-modellfälttyper mappas till SQL Server-datatyper när backend användsmssql-django.

Fälttypmappningstabell

Djangofältet SQL Server-typ Notes
AutoField int med IDENTITY(1,1) Automatisk inkrementerande primärnyckel.
BigAutoField bigint med IDENTITY(1,1) 64-bitars automatisk inkrementerande primärnyckel.
SmallAutoField smallint med IDENTITY(1,1) 16-bitars automatisk inkrementerande primärnyckel.
BooleanField bit Butiker 0 eller 1.
CharField(max_length=N) nvarchar(N) Unicode-teckendata.
DateField date Datum utan tid.
DateTimeField datetime2 Datum och tid med bråkdelar av sekunder. Använder datetimeoffset när USE_TZ=True.
DecimalField(max_digits=M, decimal_places=D) numerisk(M, D) Decimal med fast precision.
DurationField bigint Lagrad som mikrosekunder.
EmailField nvarchar(254) CharField med e-postvalidering.
FileField nvarchar(100) Lagrar filvägen.
FilePathField nvarchar(100) Lagrar filsystemets sökväg.
FloatField float 64-bitars flyttal (flyttal (53). SQL Server accepterar också synonymen double precision.
IntegerField int 32-bitars signerat heltal.
BigIntegerField bigint 64-bitars signerat heltal.
SmallIntegerField smallint 16-bitars signerat heltal.
PositiveIntegerField int Med en CHECK-begränsning.>= 0
PositiveBigIntegerField bigint Med en CHECK-begränsning.>= 0
PositiveSmallIntegerField smallint Med en CHECK-begränsning.>= 0
GenericIPAddressField Nvarchar(39) IPv4- eller IPv6-adress.
JSONField nvarchar(max) Med JSON-kontrollbegränsning.
SlugField nvarchar(50) CharField med slugvalidering.
TextField nvarchar(max) Unicode-text med obegränsad längd.
TimeField time Tid utan datum.
URLField nvarchar(200) CharField med URL-validering.
UUIDField char(32) UUID lagrad som en 32-teckens hexsträng.
BinaryField varbinär(N) Rå binär data. Backend använder max_length det för att emittera varbinär(N).
ForeignKey Samma som referensfältet Skapar ett index och en FK-begränsning.
OneToOneField Samma som referensfältet Skapar ett unikt index och FK-begränsning.
ManyToManyField N/A Skapar en mellanliggande tabell.

SQL Server-specifika beteenden

Vissa Django-fälttyper har plattformsspecifikt beteende när de används med SQL Server.

AutoFields begränsning

Att ändra ett modellfält från eller till AutoField vid migrering stöds inte. Om du behöver ändra primärnyckeltypen, skapa ett nytt fält och migrera data manuellt.

BooleanField och bit

SQL Server bittyplager0 och 1. Django motsvarar True/False dessa värden. NULL stöds med BooleanField(null=True).

Stöd för DateTimeField och tidszon

När du USE_TZ=True är i dina Django-inställningar, DateTimeField använd datetimeoffset för att lagra tidszonmedvetna datumtider. När USE_TZ=False, används datetime2.

Om du aktiverar USE_TZ efter att ha skapat kolumner måste du manuellt migrera befintliga datetime2-kolumner till datetimeoffset. För mer information, se Tidszonsstöd i mssql-django.

TextField vs CharField

SQL Server mappar både TextField och CharField till nvarchar. TextField använder nvarchar(max) medan CharField använder nvarchar(N) där N är max_length.

Alla strängfält använder nvarchar (Unicode)

Backend mssql-django mappar alla Django-strängfält (CharField, TextField, EmailField, URLField, , SlugFieldoch andra) till nvarchar, Unicode-strängtypen. Det finns inget inbyggt alternativ för att använda varchar (icke-Unicode) istället.

Detta beteende är avsiktligt. Djangos stränghantering är Unicode genomgående, och nvarchar säkerställer att alla tecken lagras korrekt oavsett språk eller kodning. Att använda nvarchar undviker dataförlust på grund av teckenuppsättningsmissanpassningar.

Avvägningar:

  • nvarchar använder 2 byte per tecken, jämfört med 1 byte per tecken för varchar med enkelbyte-sortering.
  • Gränser för indexnyckelstorlek gäller (900 byte för icke-klustrade index). En nvarchar(450) -kolumn når 900-bytesgränsen (450 x 2 byte), medan en varchar(900)- kolumn når samma gräns med enkelbytestecken.
  • Om din data är uteslutande ASCII, dubblar nvarchar lagringen jämfört med varchar.

Om du behöver varchar-kolumner:

För äldre databaser eller strikta lagringskrav, skapa ett anpassat fält som åsidosätter 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"

Försiktighet

Att använda varchar-kolumner riskerar dataförlust om icke-ASCII-tecken skrivs. Använd bara detta tillvägagångssätt när du är säker på att kolumnen lagrar ASCII-endast data, eller när du behöver matcha ett befintligt databasschema.