Hinweis
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, sich anzumelden oder das Verzeichnis zu wechseln.
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, das Verzeichnis zu wechseln.
Dieser Artikel enthält Anleitungen zum Migrieren von Django-Anwendungen von PostgreSQL, MySQL oder SQLite zu SQL Server mithilfe des mssql-django Back-Ends.
Übersicht
Djangos ORM abstrahiert die meisten Unterschiede zwischen Datenbanken, aber einige Verhaltensweisen und SQL-Dialekte unterscheiden sich je nach Datenbank-Backend. In diesem Handbuch werden die wichtigsten Unterschiede behandelt, die bei der Migration zu SQL Server auftreten.
Schritt 1: Installieren von mssql-django
Installieren Sie das mssql-django Paket und die zugehörigen Abhängigkeiten:
pip install mssql-django
Stellen Sie sicher, dass der Microsoft ODBC-Treiber für SQL Server installiert ist. Siehe mssql-django installieren für plattformspezifische Anweisungen.
Schritt 2: DATABASE-Konfiguration aktualisieren
Ersetzen Sie Ihre vorhandene Datenbankkonfiguration 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",
},
},
}
Schritt 3: Erstellen neuer Migrationen
Beginnen Sie mit einem sauberen Migrationsverlauf für SQL Server:
# Remove existing migration files (keep __init__.py)
# Then regenerate
python manage.py makemigrations
python manage.py migrate
Important
Übertragen Sie Ihre Daten mithilfe einer Datenmigration oder eines separaten ETL-Prozesses. Versuchen Sie nicht, PostgreSQL- oder MySQL-Migrationsdateien für SQL Server auszuführen.
Wichtige Unterschiede von PostgreSQL
| Merkmal | PostgreSQL | SQL Server (mssql-django) |
|---|---|---|
| Automatisch inkrementieren | SERIAL / BIGSERIAL |
IDENTITY(1,1) |
| Boolescher Typ | Nativ boolean |
bit (0 oder 1) |
| Textfelder |
text (unbegrenzt) |
nvarchar(max) |
| JSON-Unterstützung | Nativ jsonb |
nvarchar(max) mit JSON-Funktionen (SQL Server 2016+) |
| Array-Felder | ArrayField |
Wird nicht unterstützt. Verwenden Sie eine verknüpfte Tabelle oder JSON. |
| HStore-Felder | HStoreField |
Wird nicht unterstützt. Verwenden Sie stattdessen JSONField. |
| Bereichsfelder |
IntegerRangeField, BigIntegerRangeField, DateRangeField, DateTimeRangeField |
Wird nicht unterstützt. Verwenden Sie zwei separate Felder. |
| Volltextsuche |
SearchVector, SearchRank |
Verwenden Sie raw SQL mit SQL Server Volltextsuche. |
DISTINCT ON |
Unterstützt | Wird nicht unterstützt. Verwenden Sie GROUP BY oder Unterabfragen. |
DateTimeField mit Zeitzone |
timestamp with time zone |
datetimeoffset (when USE_TZ=True) oder datetime2 |
PostgreSQL-spezifische Features, die ersetzt werden sollen
Wenn Ihr Code PostgreSQL-spezifische Funktionen aus django.contrib.postgres verwendet, ersetzen Sie diese:
# 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)
Wichtige Unterschiede von MySQL
| Merkmal | MySQL | SQL Server (mssql-django) |
|---|---|---|
| Automatische Inkrementierung | AUTO_INCREMENT |
IDENTITY(1,1) |
| Boolescher Typ | tinyint(1) |
bit |
| Textfelder | longtext |
nvarchar(max) |
| JSON-Unterstützung | Native JSON (5.7 und höher) |
nvarchar(max) mit JSON-Funktionen |
| Sortierung | Pro Spalte konfigurierbar | Instanz- oder Datenbankebene (mit der Option COLLATE überschreiben) |
DateTimeField |
datetime(6) | datetimeoffset oder datetime2 |
Wichtige Unterschiede von SQLite
| Merkmal | SQLite | SQL Server (mssql-django) |
|---|---|---|
| Typprüfung | Flexible Eingabe | Strikte Typprüfung |
| Gleichzeitige Schreibvorgänge | Eingeschränkt | Vollständige Unterstützung für Parallelität |
| Maximale Anzahl der Verbindungen | Praktisch 1 Autor | Verbindungspooling mit vielen gleichzeitigen Verbindungen |
DateTimeField |
Als Text gespeichert | datetimeoffset oder datetime2 |
Sortierungsunterschiede
Die Sortierungseinstellung legt fest, wie SQL Server Text vergleicht und sortiert. Dies ist eine der häufigsten Quellen für unerwartetes Verhalten bei der Migration von PostgreSQL oder MySQL.
Groß- und Kleinschreibung
Die Standardsortierung von SQL Server (SQL_Latin1_General_CP1_CI_AS) berücksichtigt die Groß-/Kleinschreibung nicht. Bei PostgreSQL wird standardmäßig die Groß-/Kleinschreibung beachtet.
Dieses Verhalten bedeutet, dass Abfragen, die zuvor zwischen "Smith" und "smith" unterschieden, diese nach der Migration als gleich behandeln:
# On PostgreSQL: returns only exact case matches
# On SQL Server (default collation): returns both "Smith" and "smith"
User.objects.filter(last_name="Smith")
Wenn Ihre Anwendung auf Vergleiche angewiesen ist, bei denen die Groß-/Kleinschreibung beachtet wird, haben Sie zwei Möglichkeiten:
Ändern Sie die Datenbank- oder Spaltensortierung in eine Variante mit Groß-/Kleinschreibung:
-- 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;Verwenden Sie Djangos
__exactLookup mit einer Kollationsüberschreibung in rohem SQL für gezielte Abfragen.
Akzentsensitivität
Die Standardmäßige SQL Server Sortierung ist akzentsensitiv (AS), was dem Verhalten von PostgreSQL entspricht. Zeichen wie é und e werden als unterschiedlich behandelt. Wenn Sie akzentunabhängige Vergleiche benötigen, verwenden Sie eine Sortierfolge, die auf _AI endet.
Konfigurieren der Sortierung in mssql-django
Überschreiben Sie die Standardsortierung für Textfeld-Nachschlagevorgänge in Ihrer Datenbankkonfiguration:
DATABASES = {
"default": {
"ENGINE": "mssql",
"NAME": "<your-database>",
"OPTIONS": {
"driver": "ODBC Driver 18 for SQL Server",
"collation": "Latin1_General_CS_AS", # Case-sensitive
},
},
}
Note
Die Option collation in mssql-django steuert die Sortierung, die in LIKE und in Vergleichsoperationen verwendet wird, die von Djangos ORM-Lookups erzeugt werden. Die Sortierung vorhandener Spalten in der Datenbank wird nicht geändert. Verwenden Sie ALTER TABLE / ALTER COLUMN Anweisungen, um die gespeicherte Spaltensortierung zu ändern. Weitere Informationen finden Sie in SQL Server Sortierungsdokumentation.
Schritt 4: Aktualisieren von benutzerdefiniertem SQL
Wenn Ihr Code rohes SQL enthält, aktualisieren Sie ihn für SQL Server Syntax:
# 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")
Allgemeine UNTERSCHIEDE bei der SQL-Syntax:
| Vorgang | PostgreSQL/MySQL | SQL Server |
|---|---|---|
| Einschränken der Ergebnisse | LIMIT 10 |
TOP 10 oder OFFSET ... FETCH NEXT ... |
| Zeichenfolgenverkettung |
\|\| (PG) / CONCAT() |
+ oder CONCAT() |
| Boolesche Literale | TRUE / FALSE |
1 / 0 |
| Aktueller Zeitstempel | NOW() |
GETDATE(), SYSDATETIME()oder SYSDATETIMEOFFSET() für Zeitzonenfähige Werte |
| WENN NICHT VORHANDEN | CREATE TABLE IF NOT EXISTS |
Prüfen Sie sys.objects oder verwenden Sie IF NOT EXISTS |
Unterschiede bei der Transaktionsisolation
PostgreSQL verwendet MVCC (Multi-Version Concurrency Control) für seine READ COMMITTED Isolationsstufe. Leser blockieren nie Autoren und Autoren blockieren niemals Leser.
Die Standardoption von SQL Server READ COMMITTED verwendet Sperren, was bedeutet, dass Leseabfragen blockiert werden können, während sie auf den Abschluss von Schreibtransaktionen warten. Wenn in Ihrer Anwendung nach der Migration vermehrte Blockierungen auftreten, sollten Sie in Erwägung ziehen, READ COMMITTED SNAPSHOT für die Datenbank zu aktivieren:
ALTER DATABASE [<your-database>]
SET READ_COMMITTED_SNAPSHOT ON;
Dadurch verwendet SQL Server READ COMMITTED die Zeilenversionierung (ähnlich dem MVCC von PostgreSQL) anstelle von Sperren. Leser sehen die zuletzt festgeschriebene Version einer Zeile, ohne auf aktive Schreibvorgänge zu warten.
Note
READ COMMITTED SNAPSHOT erfordert zusätzlichen tempdb Speicherplatz für Zeilenversionen. Testen Sie unter realistischer Belastung, bevor Sie die Produktion aktivieren. Weitere Informationen finden Sie unter Transaktionsverwaltung in mssql-django.
Schritt 5: Migrieren von Daten
Die Datenmigrationsstrategie hängt von der Größe des Datasets ab:
Kleine Datasets (<500 MB)
Verwenden Sie Djangos 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
Große Datasets (>500 MB)
Verwenden Sie für große Migrationen spezielle Tools, um Speicherausschöpfungs- und Timeoutprobleme zu vermeiden. Djangos ORM ist nicht das richtige Tool für Massenladungen in diesem Maßstab. Umgehen Sie es beim Datenumzug und lassen Sie Django anschließend das Schema und die Anwendungslogik verwalten.
| Werkzeug | Am besten geeignet für: |
|---|---|
| SQL Server-Import/Export-Assistent | Lokale zu lokalen Migrationen mit einer GUI |
| Azure Data Factory | Jede Quelle für Azure SQL, einschließlich Hybridszenarien |
| Azure-Datenbankmigrationsdienst | Umfangreiche Migrationen mit integrierter Validierung und Rollback |
| mssql-python Massenkopie mit Apache Arrow | Benutzerdefinierte Python-Pipelines, die einen maximalen Durchsatz zwischen SQL Server, Azure SQL-Datenbank und SQL-Datenbank in Fabric benötigen |
Überprüfung nach der Migration
Überprüfen Sie nach der Migration die Konsistenz des Identitätsstartwerts für Autoinkrementspalten:
-- 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;
Wenn CurrentIdentityIdentitySeed + record_count überschreitet, neu initialisieren:
DBCC CHECKIDENT ('your_table', RESEED, new_seed);
Verwandte Inhalte
- Migrieren von Django-Apps von PostgreSQL zu SQL Server
- Installieren von mssql-django
- Zuordnungen von Django-Feldern zu SQL-Server-Datentypen
- Einschränkungen und nicht unterstützte Features in mssql-django
- Transaktionsverwaltung in mssql-django
- Unterstützung der Zeitzone in mssql-django
- JSONField mit SQL Server