Campo Django para mapeamentos do tipo SQL Server

Este artigo documenta como os tipos de campo do modelo Django mapeiam para os tipos de dados do SQL Server ao usar o mssql-django backend.

Tabela de mapeamento de tipos de campo

Campo de Django Tipo de SQL Server Observações
AutoField int com IDENTITY(1,1) Incremento automático da chave primária.
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 e-mail.
FileField nvarchar(100) Armazena o caminho do arquivo.
FilePathField nvarchar(100) Armazena o caminho do sistema de arquivos.
FloatField float Ponto flutuante de 64 bits (float(53)). SQL Server também aceita o sinônimo double precision.
IntegerField int Inteiro com sinal de 32 bits.
BigIntegerField bigint Inteiro assinado de 64 bits.
SmallIntegerField smallint Inteiro com sinal 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 string hexadecimal de 32 caracteres.
BinaryField varbinário(N) Dados binários brutos. O backend usa 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 intermediária.

Comportamentos específicos do SQL Server

Alguns tipos de campo Django apresentam comportamento específico 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 precisar mudar o tipo de chave primária, crie um novo campo e migre os dados manualmente.

BooleanField e bit

Armazena 0 do SQL Server e 1. Django mapeia True/False esses valores. NULL é suportado por BooleanField(null=True).

DateTimeField e suporte a fusos horários

Quando USE_TZ=True estiver nas configurações do Django, DateTimeField use o deslocamento de data-hora para armazenar datas com base em fusos horários. Quando USE_TZ=False, ele usa datetime2.

Se você ativar USE_TZ após criar as colunas, deve migrar manualmente as colunas datetime2 existentes para o datetimeoffset. Para mais informações, veja Suporte a fusos horários no mssql-django.

CampoTextVs Campo Carbonífero

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 há opção embutida para usar varchar (não Unicode) em vez disso.

Isso é por design. O tratamento de strings do Django é Unicode em todo o processo, e o nvarchar garante que todos os caracteres sejam armazenados corretamente, independentemente do idioma ou codificação. Usar nvarchar evita perda de dados por incompatibilidades no conjunto de caracteres.

Concessões:

  • O nvarchar usa 2 bytes por caractere, comparado a 1 byte por caractere para varchar com colações de um byte.
  • Limites de tamanho de chave de índice se aplicam (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 seus dados forem exclusivamente ASCII, o nvarchar duplica o armazenamento em comparação ao varchar.

Se você precisar de colunas varchar:

Para bancos de dados legados ou requisitos rigorosos de armazenamento, crie um campo personalizado que substitua 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"

Cuidado

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