Mappe di tipo campo Django a SQL Server

Questo articolo documenta come i tipi di campo dei modelli Django si mappano ai tipi di dati di SQL Server quando si utilizza il mssql-django backend.

Tabella di mappatura dei tipi di campo

Campo di Django Tipo SQL Server Note
AutoField int con IDENTITY(1,1) Incremento automatico della chiave primaria.
BigAutoField bigint con IDENTITY(1,1) Chiave primaria a 64 bit con incremento automatico.
SmallAutoField smallint con IDENTITY(1,1) Chiave primaria a incremento automatico a 16 bit.
BooleanField bit Negozi 0 o 1.
CharField(max_length=N) nvarchar(N) Dati caratteri Unicode.
DateField date Data senza ora.
DateTimeField datetime2 Data e ora con frazioni di secondo. Usa datetimeoffset quando USE_TZ=True.
DecimalField(max_digits=M, decimal_places=D) numerico(M, D) Decimale a precisione fissa.
DurationField bigint Memorizzata come microsecondi.
EmailField Nvarchar(254) CharField con validazione email.
FileField nvarchar(100) Memorizza il percorso del file.
FilePathField nvarchar(100) Memorizza il percorso del file system.
FloatField float Virgola mobile a 64 bit (float(53)). SQL Server accetta anche il sinonimo double precision.
IntegerField int Intero con segno a 32 bit.
BigIntegerField bigint Intero con segno a 64 bit.
SmallIntegerField smallint Intero con segno a 16 bit.
PositiveIntegerField int Con un vincolo >= 0CHECK .
PositiveBigIntegerField bigint Con un vincolo >= 0CHECK .
PositiveSmallIntegerField smallint Con un vincolo >= 0CHECK .
GenericIPAddressField Nvarchar(39) Indirizzo IPv4 o IPv6.
JSONField nvarchar(max) Con vincolo di controllo JSON. Richiede SQL Server 2016+.
SlugField nvarchar(50) CharField con validazione del slug.
TextField nvarchar(max) Testo Unicode di lunghezza illimitata.
TimeField time Tempo senza data.
URLField nvarchar(200) CharField con validazione URL.
UUIDField char(32) UUID memorizzato come stringa esadecimale di 32 caratteri.
BinaryField varbinario(N) Dati binari non elaborati. Il backend viene utilizzato max_length per emettere varbinary(N).
ForeignKey Stesso modo per il campo di riferimento Crea un vincolo di indice e FK.
OneToOneField Stesso modo per il campo di riferimento Crea un vincolo unico di indice e FK.
ManyToManyField N/A Crea una tabella intermedia.

Comportamenti specifici di SQL Server

Alcuni tipi di campo Django presentano comportamenti specifici della piattaforma quando utilizzati con SQL Server.

Limitazione dell'AutoField

Non è supportata la modifica di un campo modello da o verso AutoField al momento della migrazione. Se devi cambiare il tipo di chiave primaria, crea un nuovo campo e migra manualmente i dati.

Campo booleano e bit

SQL Server bit type store 0 e .1 Django si mappa True/False a questi valori. NULL è supportata da BooleanField(null=True).

Supporto per DateTimeField e fuso orario

Quando USE_TZ=True sei nelle impostazioni di Django, DateTimeField usa l'offset di datatimetime per memorizzare le date date consapevoli del fuso orario. Quando USE_TZ=False, usa datetime2.

Se abiliti USE_TZ le colonne dopo aver creato le colonne, devi migrare manualmente le colonne esistenti di datetime2 a datetimeoffset. Per ulteriori informazioni, vedi Supporto per fusi orari in mssql-django.

Campotesto vs Campo di Carta

SQL Server mappa entrambi TextField e CharField a nvarchar. TextField usa nvarchar(max) mentre CharField usa nvarchar(N) dove N è max_length.

Tutti i campi stringa usano nvarchar (Unicode)

Il mssql-django backend mappa tutti i campi di stringhe di Django (CharField, TextField, EmailField, URLField, SlugFielde altri) a nvarchar, il tipo di stringa Unicode. Non c'è un'opzione integrata per usare varchar (non-Unicode) invece.

Questo è intenzionale. La gestione delle stringhe di Django è Unicode per tutto il tempo, e nvarchar garantisce che tutti i caratteri vengano memorizzati correttamente indipendentemente dalla lingua o dalla codifica. L'uso di nvarchar evita la perdita di dati dovuta a disallineamenti nel set di caratteri.

Compromessi:

  • NVARchar utilizza 2 byte per carattere, rispetto a 1 byte per carattere per varchar con collazioni a singolo byte.
  • Si applicano limiti di dimensione della chiave dell'indice (900 byte per indici non clusterizzati). Una colonna nvarchar(450) raggiunge il limite di 900 byte (450 x 2 byte), mentre una colonna varchar(900) raggiunge lo stesso limite usando caratteri a singolo byte.
  • Se i tuoi dati sono esclusivamente ASCII, nvarchar raddoppia la memoria rispetto a varchar.

Se ti servono le colonne varchar:

Per database legacy o requisiti di storage rigorosi, crea un campo personalizzato che sovrascriva 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"

Attenzione

L'uso delle colonne varchar rischia la perdita di dati se vengono scritti caratteri non ASCII. Usa questo approccio solo quando sei certo che la colonna memorizzi dati solo ASCII, o quando devi corrispondere a uno schema di database esistente.