Mappings typu pole Django do SQL Server

Ten artykuł dokumentuje, jak typy pól modeli Django mapują się na typy danych SQL Server podczas korzystania z backendumssql-django.

Tabela mapowania typów pól

Pole Django Typ programu SQL Server Notatki
AutoField int z IDENTITY(1,1) Automatyczne zwiększanie klucza głównego.
BigAutoField bigint z IDENTITY(1,1) 64-bitowy klucz główny automatycznie przyrastający.
SmallAutoField smallint z IDENTITY(1,1) 16-bitowy klucz główny automatycznie przyrastający.
BooleanField bit Magazyny 0 lub 1.
CharField(max_length=N) nvarchar(N) Dane znaków Unicode.
DateField date Data bez godziny.
DateTimeField datetime2 Data i czas z ułamkami sekund. Używa datetimeoffset, gdy USE_TZ=True.
DecimalField(max_digits=M, decimal_places=D) numeryczne(M, D) Dziesiętny o stałej dokładności.
DurationField bigint Przechowywane w mikrosekundach.
EmailField nvarchar(254) CharField z walidacją e-mail.
FileField nvarchar(100) Przechowuje ścieżkę pliku.
FilePathField nvarchar(100) Przechowuje ścieżkę systemu plików.
FloatField float zmiennoprzecinkowy 64-bitowy (float(53)). SQL Server akceptuje również synonim double precision.
IntegerField int 32-bitowa liczba całkowita ze znakiem.
BigIntegerField bigint 64-bitowa liczba całkowita ze znakiem.
SmallIntegerField smallint 16-bitowa liczba całkowita ze znakiem.
PositiveIntegerField int Z ograniczeniem >= 0CHECK .
PositiveBigIntegerField bigint Z ograniczeniem >= 0CHECK .
PositiveSmallIntegerField smallint Z ograniczeniem >= 0CHECK .
GenericIPAddressField nvarchar(39) Adres IPv4 lub IPv6.
JSONField nvarchar(max) Z ograniczeniem JSON check constraint.
SlugField nvarchar(50) CharField z walidacją slug.
TextField nvarchar(max) Tekst Unicode o nieograniczonej długości.
TimeField time Czas bez daty.
URLField nvarchar(200) CharField z weryfikacją URL.
UUIDField char(32) UUID przechowywany jako 32-znakowy ciąg sześciasnowy.
BinaryField varbinary(N) Surowe dane binarne. Backend emituje max_lengthwarbinary(N).
ForeignKey Tak samo jak pole referencyjne Tworzy ograniczenie indeksu i FK.
OneToOneField Tak samo jak pole referencyjne Tworzy unikalny indeks i ograniczenie FK.
ManyToManyField N/A Tworzy tabelę pośrednią.

Zachowania specyficzne dla SQL Server

Niektóre typy pól Django mają specyficzne dla platformy zachowanie podczas korzystania z SQL Server.

Ograniczenie AutoField

Nie jest obsługiwana zmiana pola modelu z lub do AutoField podczas migracji. Jeśli musisz zmienić główny typ klucza, stwórz nowe pole i ręcznie przenieś dane.

BooleanField i bit

SQL Server zapisuje typ 0 i 1. Django odwzorowuje True/False się na te wartości. NULL jest wspierany przez BooleanField(null=True).

DateTimeField i wsparcie dla stref czasowych

W USE_TZ=True ustawieniach Django używaj DateTimeFielddatetimeoffset do przechowywania datetimetime, które są świadome strefy czasowej. Gdy USE_TZ=False, używa datetime2.

Jeśli włączysz to USE_TZ po utworzeniu kolumn, musisz ręcznie przenieść istniejące kolumny datetime2 do datetimeoffset. Więcej informacji można znaleźć w artykule Wsparcie dla stref czasowych w mssql-django.

TextField kontra CharField

SQL Server mapuje zarówno toTextField, jak i CharField na nvarchar. TextFieldużywa nvarchar(max), natomiast CharFieldnvarchar(N), gdzie N jest .max_length

Wszystkie pola znaków znaków używają nvarchar (Unicode)

Backend mapuje mssql-django wszystkie pola łańcuchowe Django (CharField, TextField, EmailField, URLField, , SlugFieldi inne) na nvarchar, typ ciągu znaków Unicode. Nie ma wbudowanej opcji używania varchar (nie-Unicode).

Jest to celowe. Obsługa ciągów znaków znaków Django jest w całości Unicode, a nvarchar zapewnia, że wszystkie znaki są przechowywane poprawnie, niezależnie od języka czy kodowania. Użycie nvarchar pozwala uniknąć utraty danych spowodowanych niedopasowaniem zestawów znaków.

Kompromisy:

  • nvarchar używa 2 bajtów na znak, podczas gdy varchar przy pojedynczych bajtach używa 1 bajtu na znak.
  • Obowiązują limity rozmiaru klucza indeksowego (900 bajtów dla indeksów nieklastrowanych). Kolumna nvarchar(450) osiąga limit 900 bajtów (450 x 2 bajty), natomiast kolumna varchar(900) osiąga ten sam limit przy użyciu znaków jednobajtowych.
  • Jeśli Twoje dane są wyłącznie ASCII, nvarchar podwaja pamięć w porównaniu do varchar.

Jeśli potrzebujesz kolumn varchar:

Dla baz danych starszych lub rygorystycznych wymagań dotyczących pamięci utworz niestandardowe pole, które nadpisuje 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"

Caution

Używanie kolumn varchar ryzykuje utratę danych, jeśli zapisywane są znaki nie-ASCII. Stosuj to podejście tylko wtedy, gdy masz pewność, że kolumna przechowuje dane tylko ASCII lub gdy musisz dopasować istniejący schemat bazy danych.