Django uygulamalarını diğer veritabanlarından SQL Server geçirme

Bu makale, Django uygulamalarını PostgreSQL, MySQL veya SQLite'tan mssql-django arka ucunu kullanarak SQL Server'a geçirmek için rehberlik sağlar.

Overview

Django'nun ORM'i çoğu veritabanı farklarını soyutlar, ancak bazı davranışlar ve SQL diyalektleri arka uçlar arasında farklılık gösterir. Bu kılavuz, SQL Server geçiş yaparken karşılaştığınız önemli farkları kapsar.

1. Adım: mssql-django'yu yükleme

mssql-django Paketi ve bağımlılıklarını yükleyin:

pip install mssql-django

SQL Server için Microsoft ODBC Sürücüsünün yüklendiğinden emin olun. Platforma özgü yönergeler için bkz . mssql-django'yu yükleme .

2. Adım: Yapılandırmayı güncelleştirme DATABASE

içindeki settings.pymevcut veritabanı yapılandırmanızı değiştirin:

# 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",
        },
    },
}

3. Adım: Yeni geçişler oluşturma

SQL Server için temiz bir geçiş geçmişiyle başlayın:

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

Important

Veri geçişi veya ayrı BIR ETL işlemi kullanarak verilerinizi aktarma. PostgreSQL veya MySQL geçiş dosyalarını SQL Server karşı çalıştırmayı denemeyin.

PostgreSQL'den önemli farklar

Feature PostgreSQL SQL Server (mssql-django)
Otomatik artırma SERIAL / BIGSERIAL IDENTITY(1,1)
Boole türü Yerleşik boolean bit (0 veya 1)
Metin alanları text (sınırsız) nvarchar(max)
JSON desteği Yerel jsonb JSON işlevleriyle nvarchar(max) (SQL Server 2016+)
Dizi alanları ArrayField Desteklenmiyor. İlgili bir tablo veya JSON kullanın.
HStore alanları HStoreField Desteklenmiyor. Bunun yerine JSONField kullanın.
Aralık alanları IntegerRangeField, BigIntegerRangeField, DateRangeField, DateTimeRangeField Desteklenmiyor. İki ayrı alan kullanın.
Tam metin arama SearchVector, SearchRank SQL Server tam metin aramasıyla ham SQL kullanın.
DISTINCT ON Destekleniyor Desteklenmiyor. Veya alt sorgular kullanın GROUP BY .
DateTimeField saat dilimi ile timestamp with time zone datetimeoffset (when USE_TZ=True) veya datetime2

Değiştirilecek PostgreSQL'e özgü özellikler

Kodunuz postgreSQL'e django.contrib.postgresözgü özelliklerini kullanıyorsa bunları değiştirin:

# 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)

MySQL'den önemli farklar

Feature MySQL SQL Server (mssql-django)
Otomatik artırma AUTO_INCREMENT IDENTITY(1,1)
Boole türü tinyint(1) bit
Metin alanları longtext nvarchar(max)
JSON desteği Yerel JSON (5.7 ve üzeri) JSON işlevleriyle nvarchar(max)
Collation Sütun başına yapılandırılabilir İnstans veya veritabanı düzeyi (COLLATE seçeneğiyle geçersiz kılınabilir)
DateTimeField datetime(6) datetimeoffset veya datetime2

SQLite'ten önemli farklar

Feature SQLite SQL Server (mssql-django)
Türün zorunlu kılınması Esnek yazma Sıkı tür denetimi
Eşzamanlı yazma işlemleri Sınırlı Tam eşzamanlılık desteği
En fazla bağlantı sayısı Fiilen 1 yazar Birçok eşzamanlı bağlantı ile bağlantı havuzu oluşturma
DateTimeField Metin olarak depolanır datetimeoffset veya datetime2

Harmanlama farklılıkları

Harmanlama, SQL Server metinleri karşılaştırma ve sıralama şeklini denetler. Bu, PostgreSQL veya MySQL'den geçiş yaparken en yaygın beklenmeyen davranış kaynaklarından biridir.

Büyük/küçük harfe duyarlı

SQL Server’ın varsayılan harmanlaması (SQL_Latin1_General_CP1_CI_AS) büyük/küçük harfe duyarlı değildir. PostgreSQL varsayılan olarak büyük/küçük harfe duyarlıdır.

Bu davranış, geçiş sonrasında daha önce aralarında ayrım "Smith""smith" yapıp bunları eşit olarak değerlendiren sorguların olduğu anlamına gelir:

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

Uygulamanız büyük/küçük harfe duyarlı karşılaştırmalara bağlıysa iki seçeneğiniz vardır:

  • Veritabanı veya sütun harmanlamasını büyük/küçük harfe duyarlı bir değişken olarak değiştirin:

    -- 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;
    
  • Hedefli sorgular için ham SQL'de, bir harmanlama geçersiz kılmasıyla Django'nun __exact arama ifadesini kullanın.

Aksan duyarlılığı

Varsayılan SQL Server harmanlama, PostgreSQL'in davranışıyla eşleşen vurguya duyarlıdır (AS ). é ve e gibi karakterler farklı kabul edilir. Aksan duyarsız karşılaştırmalara ihtiyacınız varsa, _AI ile biten bir sıralama kullanın.

mssql-django'da harmanlamayı yapılandırma

Veritabanı yapılandırmanızda metin alanı aramaları için varsayılan harmanlamayı geçersiz kılın:

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

Note

mssql-django içindeki collation seçeneği, LIKE ve Django’nun ORM aramalarının oluşturduğu karşılaştırma işlemlerinde kullanılan karşılaştırma sıralamasını denetler. Veritabanındaki mevcut sütunların harmanlamasını değiştirmez. Saklanan sütunun harmanlama ayarını değiştirmek için ALTER TABLE / ALTER COLUMN komutlarını kullanın. Daha fazla bilgi için SQL Server harmanlama belgelerine bakın.

4. Adım: Özel SQL'i güncelleştirme

Kodunuz ham SQL içeriyorsa, SQL Server söz dizimi için güncelleştirin:

# 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")

Yaygın SQL söz dizimi farklılıkları:

Operation PostgreSQL/MySQL SQL Server
Sonuçları sınırla LIMIT 10 TOP 10 veya OFFSET ... FETCH NEXT ...
Dize birleştirme \|\| (PG) / CONCAT() + veya CONCAT()
Boole sabitleri TRUE / FALSE 1 / 0
Geçerli zaman damgası NOW() GETDATE(), SYSDATETIME()veya SYSDATETIMEOFFSET() saat dilimini kullanan değerler için
MEVCUT DEĞİLSE CREATE TABLE IF NOT EXISTS Kontrol edin sys.objects veya IF NOT EXISTS kullanın

İşlem yalıtımı farklılıkları

PostgreSQL, yalıtım düzeyi için READ COMMITTED MVCC (Çok Sürümlü Eşzamanlılık Denetimi) kullanır. Okuyucular yazarları engellemez ve yazarlar okuyucuları asla engellemez.

SQL Server varsayılan olarak READ COMMITTED kilitlemeyi kullanır; bu da okuma sorgularının yazma işlemlerinin tamamlanmasını beklerken engel olabileceği anlamına gelir. Uygulamanızda geçişten sonra engelleme artışı yaşanıyorsa, veritabanında etkinleştirmeyi READ COMMITTED SNAPSHOT göz önünde bulundurun:

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

Bu, SQL Server'ın READ COMMITTED öğesini kilitleme yerine satır sürümlendirmesi (PostgreSQL'in MVCC'sine benzer) kullanacak şekilde değiştirir. Okuyucular, aktif yazma işlemlerini beklemeden bir satırın son onaylanmış sürümünü görür.

Note

READ COMMITTED SNAPSHOT satır sürümleri için ek tempdb alan gerektirir. Üretimde etkinleştirmeden önce gerçekçi yük altında test edin. Daha fazla bilgi için bkz. mssql-django'da işlem yönetimi.

5. Adım: Verileri geçirme

Veri geçişi stratejisi veri kümesi boyutuna bağlıdır:

Küçük veri kümeleri (<500 MB)

Django'nun dumpdata/loaddatakullanın:

# 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

Büyük veri kümeleri (>500 MB)

Büyük geçişlerde, bellek tükenmesini ve zaman aşımı sorunlarını önlemek için özel araçları kullanın. Django'nun ORM'i bu ölçekte toplu yükler için doğru araç değildir. Veri taşıma için bunu atlayın ve ardından Django'ya şema ve uygulama mantığını yönetme izni verin.

Tool En iyi kullanım alanları
SQL Server İçeri ve Dışarı Aktarma Sihirbazı Grafik kullanıcı arayüzüyle yerinden yerine geçişler
Azure Data Factory Karma senaryolar da dahil olmak üzere Azure SQL için herhangi bir kaynak
Azure Veritabanı Geçiş Hizmeti Yerleşik doğrulama ve geri alma ile büyük ölçekli geçişler
Apache Arrow ile mssql-python toplu kopyalama Fabric'daki SQL Server, Azure SQL Veritabanı ve SQL veritabanı arasında en yüksek aktarım hızına ihtiyaç duyan özel Python işlem hatları

Geçiş sonrası doğrulama

Taşıma işleminden sonra, otomatik artan sütunlar için kimlik başlangıç değeri tutarlılığını doğrulayın:

-- 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;

değerini aşarsa CurrentIdentityIdentitySeed + record_countyeniden görüntülenir:

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