Campo Django para mapeamentos do tipo SQL Server

Este artigo documenta como os tipos de campo dos modelos Django correspondem aos tipos de dados do SQL Server ao utilizar o mssql-django backend.

Tabela de mapeamento de tipos de campo

Campo de Django Tipo de SQL Server Notes
AutoField int com IDENTITY(1,1) A chave primária com incremento automático.
BigAutoField bigint com IDENTITY(1,1) Chave primária auto-incrementante de 64 bits.
SmallAutoField smallint com IDENTITY(1,1) Chave primária auto-incrementante de 16 bits.
BooleanField bit Lojas 0 ou 1.
CharField(max_length=N) nvarchar(N) Dados de caracteres Unicode.
DateField date Data sem hora.
DateTimeField datetime2 Data e hora com frações de segundo. Usa datatimeoffset quando USE_TZ=True.
DecimalField(max_digits=M, decimal_places=D) numérico(M, D) Decimal de precisão fixa.
DurationField bigint Armazenados como microssegundos.
EmailField nvarchar(254) Charfield com validação de email.
FileField nvarchar(100) Armazena o caminho do ficheiro.
FilePathField nvarchar(100) Armazena o caminho do sistema de ficheiros.
FloatField float Ponto flutuante de 64 bits (float(53)). O SQL Server também aceita o sinónimo double precision.
IntegerField int Inteiro assinado de 32 bits.
BigIntegerField bigint Inteiro assinado de 64 bits.
SmallIntegerField smallint Inteiro assinado de 16 bits.
PositiveIntegerField int Com uma restrição >= 0CHECK .
PositiveBigIntegerField bigint Com uma restrição >= 0CHECK .
PositiveSmallIntegerField smallint Com uma restrição >= 0CHECK .
GenericIPAddressField nvarchar(39) Endereço IPv4 ou IPv6.
JSONField nvarchar(max) Com restrição de verificação JSON.
SlugField nvarchar(50) CharField com validação de slug.
TextField nvarchar(max) Texto Unicode de comprimento ilimitado.
TimeField time Tempo sem data.
URLField Nvarchar(200) CharField com validação de URL.
UUIDField char(32) UUID armazenado como uma cadeia hexadecimal de 32 caracteres.
BinaryField varbinário(N) Dados binários brutos. O backend é usado max_length para emitir varbinary(N).
ForeignKey Igual ao campo referenciado Cria uma restrição de índice e FK.
OneToOneField Igual ao campo referenciado Cria uma restrição única de índice e FK.
ManyToManyField N/A Cria uma tabela intermédia.

Comportamentos específicos do SQL Server

Alguns tipos de campos Django apresentam comportamentos específicos da plataforma quando usados com SQL Server.

Limitação do AutoField

Alterar um campo de modelo de ou para AutoField no momento da migração não é suportado. Se precisares de alterar o tipo de chave primária, cria um novo campo e migra os dados manualmente.

BooleanField e bit

Armazenamento 0 do SQL Server e 1. O Django corresponde True/False a estes valores. NULL é suportado por BooleanField(null=True).

DateTimeField e suporte a fusos horários

Quando USE_TZ=True estiver nas definições do Django, DateTimeField usa o desfasamento de data-hora para guardar as datas com base no fuso horário. Quando USE_TZ=False, usa datetime2.

Se ativares USE_TZ depois de criar colunas, tens de migrar manualmente as colunas datetime2 existentes para datetimeoffset. Para mais informações, consulte Suporte a fusos horários no mssql-django.

TextField vs CharField

O SQL Server mapeia ambos TextField e CharField para nvarchar. TextField usa nvarchar(max) enquanto CharField usa nvarchar(N) onde N é max_length.

Todos os campos de string usam nvarchar (Unicode)

O mssql-django backend mapeia todos os campos de string de Django (CharField, TextField, EmailField, URLField, SlugField, e outros) para nvarchar, o tipo de string Unicode. Não existe uma opção incorporada para usar varchar (não Unicode) em vez disso.

Isso é intencional. O tratamento das strings do Django é Unicode em todo o processo, e o nvarchar garante que todos os caracteres são armazenados corretamente, independentemente da linguagem ou codificação. Usar nvarchar evita a perda de dados devido a desajustes no conjunto de caracteres.

Compromissos:

  • O nvarchar usa 2 bytes por carácter, comparado com 1 byte por carácter para varchar com colações de um byte.
  • Aplicam-se limites de tamanho de chave de índice (900 bytes para índices não clusterizados). Uma coluna nvarchar(450) atinge o limite de 900 bytes (450 x 2 bytes), enquanto uma coluna varchar(900) atinge o mesmo limite usando caracteres de um byte.
  • Se os teus dados forem exclusivamente ASCII, o nvarchar duplica o armazenamento em comparação com o varchar.

Se precisares de colunas varchar:

Para bases de dados legadas ou requisitos rigorosos de armazenamento, crie um campo personalizado que sobreponha 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"

Atenção

Usar colunas varchar corre o risco de perda de dados se forem escritos caracteres não ASCII. Use esta abordagem apenas quando tiver a certeza de que a coluna armazena dados apenas em ASCII, ou quando precisar de corresponder a um esquema de base de dados existente.