Django-apps migreren van andere databases naar SQL Server

Dit artikel bevat richtlijnen voor het migreren van Django-toepassingen van PostgreSQL, MySQL of SQLite naar SQL Server met behulp van de mssql-django back-end.

Overview

Django's ORM abstraheert de meeste databaseverschillen, maar sommige gedragingen en SQL-dialecten verschillen per back-end. In deze handleiding worden de belangrijkste verschillen besproken die u ondervindt bij het migreren naar SQL Server.

Stap 1: mssql-django installeren

Installeer het mssql-django pakket en de bijbehorende afhankelijkheden:

pip install mssql-django

Zorg ervoor dat het MICROSOFT ODBC-stuurprogramma voor SQL Server is geïnstalleerd. Zie Mssql-django installeren voor platformspecifieke instructies.

Stap 2: Configuratie bijwerken DATABASE

Vervang uw bestaande databaseconfiguratie in settings.py:

# Example: From PostgreSQL
# DATABASES = {
#     "default": {
#         "ENGINE": "django.db.backends.postgresql",
#         "NAME": "mydb",
#     },
# }

# To SQL Server
DATABASES = {
    "default": {
        "ENGINE": "mssql",
        "NAME": "<your-database>",
        "USER": "<your-username>",
        "PASSWORD": "<your-password>",
        "HOST": "<your-server>",
        "PORT": "1433",
        "OPTIONS": {
            "driver": "ODBC Driver 18 for SQL Server",
        },
    },
}

Stap 3: Nieuwe migraties maken

Begin met een schone migratiegeschiedenis voor SQL Server:

# Remove existing migration files (keep __init__.py)
# Then regenerate
python manage.py makemigrations
python manage.py migrate

Important

Gegevens overdragen met behulp van een gegevensmigratie of een afzonderlijk ETL-proces. Probeer postgreSQL- of MySQL-migratiebestanden niet uit te voeren op SQL Server.

Belangrijke verschillen met PostgreSQL

Eigenschap PostgreSQL SQL Server (mssql-django)
Automatisch verhogen SERIAL / BIGSERIAL IDENTITY(1,1)
Booleaanse waardetype Native boolean bit (0 of 1)
Tekstvelden text (onbeperkt) nvarchar(max)
JSON-ondersteuning Native jsonb nvarchar(max) met JSON-functies (SQL Server 2016+)
Matrixvelden ArrayField Wordt niet ondersteund. Gebruik een gerelateerde tabel of JSON.
HStore-velden HStoreField Wordt niet ondersteund. Gebruik in plaats daarvan JSONField.
Bereikvelden IntegerRangeField,BigIntegerRangeField,DateRangeField,DateTimeRangeField Wordt niet ondersteund. Gebruik twee afzonderlijke velden.
Zoeken in volledige tekst SearchVector, SearchRank Gebruik onbewerkte SQL met SQL Server zoeken in volledige tekst.
DISTINCT ON Supported Wordt niet ondersteund. Gebruik GROUP BY of subquery’s.
DateTimeField met tijdzone timestamp with time zone datetimeoffset (indien USE_TZ=True) of datetime2

PostgreSQL-specifieke functies die moeten worden vervangen

Als uw code gebruikmaakt van PostgreSQL-specifieke mogelijkheden van django.contrib.postgres, vervang deze:

# PostgreSQL ArrayField - replace with JSONField or related table
# Before
from django.contrib.postgres.fields import ArrayField
tags = ArrayField(models.CharField(max_length=50))

# After (using JSONField)
tags = models.JSONField(default=list)

# PostgreSQL HStoreField - replace with JSONField
# Before
from django.contrib.postgres.fields import HStoreField
metadata = HStoreField()

# After
metadata = models.JSONField(default=dict)

Belangrijkste verschillen van MySQL

Eigenschap MySQL SQL Server (mssql-django)
Automatisch verhogen AUTO_INCREMENT IDENTITY(1,1)
Booleaanse waardetype tinyint(1) bit
Tekstvelden longtext nvarchar(max)
JSON-ondersteuning Systeemeigen JSON (5.7 en hoger) nvarchar(max) met JSON-functies
Collation Configureerbaar per kolom Exemplaar- of databaseniveau (overschrijven met COLLATE optie)
DateTimeField datetime(6) datetimeoffset of datetime2

Belangrijkste verschillen van SQLite

Eigenschap SQLite SQL Server (mssql-django)
Afdwinging van typen Flexibel typen Strikte typecontrole
Gelijktijdige schrijfbewerkingen Limited Volledige gelijktijdigheidsondersteuning
Maximum aantal verbindingen Feitelijk 1 auteur Connectionpooling met veel gelijktijdige verbindingen
DateTimeField Opgeslagen als tekst datetimeoffset of datetime2

Collatieverschillen

Met collatie bepaalt u hoe SQL Server tekst vergelijkt en sorteert. Dit is een van de meest voorkomende bronnen van onverwacht gedrag bij het migreren vanuit PostgreSQL of MySQL.

Hoofdlettergevoelig

De standaardsortering van SQL Server (SQL_Latin1_General_CP1_CI_AS) is niet hoofdlettergevoelig. PostgreSQL is standaard hoofdlettergevoelig.

Dit gedrag betekent dat query's na de migratie die eerder onderscheid maakten tussen "Smith" en "smith", deze als gelijk beschouwen:

# On PostgreSQL: returns only exact case matches
# On SQL Server (default collation): returns both "Smith" and "smith"
User.objects.filter(last_name="Smith")

Als uw toepassing afhankelijk is van hoofdlettergevoelige vergelijkingen, hebt u twee opties:

  • Wijzig de database- of kolomsortering in een hoofdlettergevoelige variant:

    -- Database-level (affects all new columns)
    ALTER DATABASE [<your-database>] COLLATE Latin1_General_CS_AS;
    
    -- Column-level (for specific columns)
    ALTER TABLE [<your-table>]
    ALTER COLUMN [<column-name>] NVARCHAR (150) COLLATE Latin1_General_CS_AS;
    
  • Gebruik Django's __exact lookup met een overschrijving van de collatie in raw SQL voor gerichte query's.

Accentgevoeligheid

De standaard SQL Server sortering is accentgevoelig (AS), die overeenkomt met het gedrag van PostgreSQL. Tekens zoals é en e worden als verschillend behandeld. Als u accentongevoelige vergelijkingen nodig hebt, gebruikt u een sortering die eindigt op _AI.

Collation configureren in mssql-django

Overschrijf de standaardsortering voor opzoekacties voor tekstvelden in de databaseconfiguratie:

DATABASES = {
    "default": {
        "ENGINE": "mssql",
        "NAME": "<your-database>",
        "OPTIONS": {
            "driver": "ODBC Driver 18 for SQL Server",
            "collation": "Latin1_General_CS_AS",  # Case-sensitive
        },
    },
}

Note

De collation optie in mssql-django bepaalt de sortering die wordt gebruikt in LIKE en vergelijkingsbewerkingen die worden gegenereerd door de ORM-zoekacties van Django. De sortering van bestaande kolommen in de database wordt niet gewijzigd. Als u de opgeslagen kolomsortering wilt wijzigen, gebruikt u ALTER TABLE / ALTER COLUMN instructies. Zie SQL Server sorteringsdocumentatie voor meer informatie.

Stap 4: Aangepaste SQL bijwerken

Als uw code onbewerkte SQL bevat, werkt u deze bij voor SQL Server syntaxis:

# PostgreSQL syntax
# cursor.execute("SELECT * FROM products LIMIT 10 OFFSET 20")

# SQL Server syntax
cursor.execute("SELECT * FROM products ORDER BY id OFFSET 20 ROWS FETCH NEXT 10 ROWS ONLY")

Veelvoorkomende verschillen in SQL-syntaxis:

Operation PostgreSQL/MySQL SQL Server
Resultaten beperken LIMIT 10 TOP 10 of OFFSET ... FETCH NEXT ...
Tekenreeks samenvoeging \|\| (PG) / CONCAT() + of CONCAT()
Booleaanse letterlijke waarden TRUE / FALSE 1 / 0
Huidige tijdstempel NOW() GETDATE(), SYSDATETIME()of SYSDATETIMEOFFSET() voor tijdzonebewuste waarden
ALS NIET BESTAAT CREATE TABLE IF NOT EXISTS Controleer sys.objects of gebruik IF NOT EXISTS

Verschillen in transactieisolatie

PostgreSQL maakt gebruik van MVCC (Gelijktijdigheidsbeheer met meerdere versies) voor het READ COMMITTED isolatieniveau. Lezers blokkeren schrijvers nooit en schrijvers blokkeren lezers nooit.

de standaardinstelling READ COMMITTED van SQL Server maakt gebruik van vergrendeling, wat betekent dat leesquery's kunnen worden geblokkeerd terwijl wordt gewacht tot schrijftransacties zijn voltooid. Als uw toepassing na de migratie meer blokkeringen ondervindt, kunt u overwegen READ COMMITTED SNAPSHOT in te schakelen op de database:

ALTER DATABASE [<your-database>]
SET READ_COMMITTED_SNAPSHOT ON;

Hierdoor gebruikt SQL Server READ COMMITTED rijversiebeheer (vergelijkbaar met de MVCC van PostgreSQL) in plaats van vergrendeling. Lezers zien de laatste vastgelegde versie van een rij zonder te wachten op actieve schrijvers.

Note

READ COMMITTED SNAPSHOT vereist extra tempdb ruimte voor rijversies. Test onder realistische belasting voordat u productie inschakelt. Zie Transactiebeheer in mssql-django voor meer informatie.

Stap 5: Gegevens migreren

De strategie voor gegevensmigratie is afhankelijk van de grootte van de gegevensset:

Kleine gegevenssets (<500 MB)

Gebruik Django's dumpdata/loaddata:

# On the source database
python manage.py dumpdata --natural-foreign --natural-primary -o data.json

# Switch settings.py to SQL Server, then:
python manage.py migrate
python manage.py loaddata data.json

Grote gegevenssets (>500 MB)

Voor grote migraties gebruikt u gespecialiseerde hulpprogramma's om geheugenuitputting en time-outproblemen te voorkomen. Django's ORM is niet het juiste hulpprogramma voor bulksgewijs laden op deze schaal. Sla deze over voor de verplaatsing van gegevens en laat Django daarna schema- en toepassingslogica beheren.

Tool Ideaal voor
SQL Server Import- en Exportwizard On-premises naar on-premises migraties met een GUI
Azure Data Factory Elke bron voor Azure SQL, inclusief hybride scenario's
Azure Database Migration Service Grootschalige migraties met ingebouwde validatie en terugdraaien
mssql-python bulkkopie met Apache Arrow Aangepaste Python-pijplijnen die de maximale doorvoer nodig hebben tussen SQL Server, Azure SQL Database en SQL-database in Fabric

Validatie na migratie

Controleer na de migratie de consistentie van de seedwaarde van identiteitskolommen met automatisch oplopende waarden:

-- Check identity seed and current value for all tables
SELECT 
    TABLE_NAME,
    IDENT_SEED(TABLE_SCHEMA + '.' + TABLE_NAME) AS IdentitySeed,
    IDENT_INCR(TABLE_SCHEMA + '.' + TABLE_NAME) AS IdentityIncrement,
    IDENT_CURRENT(TABLE_SCHEMA + '.' + TABLE_NAME) AS CurrentIdentity
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_TYPE = 'BASE TABLE'
    AND OBJECTPROPERTY(OBJECT_ID(TABLE_SCHEMA + '.' + TABLE_NAME), 'TableHasIdentity') = 1
ORDER BY TABLE_NAME;

Als CurrentIdentity groter is dan IdentitySeed + record_count, opnieuw seeden:

DBCC CHECKIDENT ('your_table', RESEED, new_seed);