이 문서에서는 PostgreSQL, MySQL 또는 SQLite에서 백 엔드를 사용하여 mssql-django django 애플리케이션을 SQL Server 마이그레이션하기 위한 지침을 제공합니다.
Overview
Django의 ORM은 대부분의 데이터베이스 차이점을 추상화하지만 일부 동작과 SQL 언어는 백 엔드마다 다릅니다. 이 가이드에서는 SQL Server 마이그레이션할 때 발생하는 주요 차이점에 대해 설명합니다.
1단계: mssql-django 설치
mssql-django 패키지 및 해당 종속성을 설치합니다.
pip install mssql-django
Microsoft ODBC Driver for SQL Server 설치되어 있는지 확인합니다. 플랫폼별 지침 은 mssql-django 설치 를 참조하세요.
2단계: 구성 업데이트 DATABASE
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",
},
},
}
3단계: 새 마이그레이션 만들기
SQL Server 대한 정리된 마이그레이션 기록으로 시작합니다.
# Remove existing migration files (keep __init__.py)
# Then regenerate
python manage.py makemigrations
python manage.py migrate
Important
데이터 마이그레이션 또는 별도의 ETL 프로세스를 사용하여 데이터를 전송합니다. SQL Server 대해 PostgreSQL 또는 MySQL 마이그레이션 파일을 실행하지 마세요.
PostgreSQL의 주요 차이점
| 특징 | PostgreSQL | SQL Server(mssql-django) |
|---|---|---|
| 자동 증가 | SERIAL / BIGSERIAL |
IDENTITY(1,1) |
| 불리언 자료형 | 네이티브 boolean |
bit (0 또는 1) |
| 텍스트 필드 |
text (무제한) |
nvarchar(max) |
| JSON 지원 | 네이티브 jsonb |
jSON 함수를 사용하는 nvarchar(max) (SQL Server 2016 이상) |
| 배열 필드 | ArrayField |
지원되지 않습니다. 관련 테이블 또는 JSON을 사용합니다. |
| HStore 필드 | HStoreField |
지원되지 않습니다.
JSONField를 대신 사용하세요. |
| 범위 필드 |
IntegerRangeField, BigIntegerRangeField, , DateRangeField, DateTimeRangeField |
지원되지 않습니다. 두 개의 별도 필드를 사용합니다. |
| 전체 텍스트 검색 |
SearchVector, SearchRank |
SQL Server 전체 텍스트 검색에 원시 SQL을 사용합니다. |
DISTINCT ON |
지원됨 | 지원되지 않습니다.
GROUP BY 또는 하위 쿼리를 사용하세요. |
DateTimeField 시간대 포함 |
timestamp with time zone |
datetimeoffset (when USE_TZ=True) 또는 datetime2 |
교체할 PostgreSQL 전용 기능
코드에서 django.contrib.postgresPostgreSQL 관련 기능을 사용하는 경우 다음을 대체합니다.
# 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의 주요 차이점
| 특징 | MySQL | SQL Server(mssql-django) |
|---|---|---|
| 자동 증가 | AUTO_INCREMENT |
IDENTITY(1,1) |
| 불리언 자료형 | tinyint(1) |
bit |
| 텍스트 필드 | longtext |
nvarchar(max) |
| JSON 지원 | 네이티브 JSON (5.7 이상) |
JSON 함수를 사용하는 nvarchar(max) |
| Collation | 열별 구성 가능 | 인스턴스 또는 데이터베이스 수준(옵션으로 COLLATE 재정의) |
DateTimeField |
datetime(6) | datetimeoffset 또는 datetime2 |
SQLite의 주요 차이점
| 특징 | SQLite | SQL Server(mssql-django) |
|---|---|---|
| 유형 강제 | 유연한 입력 | 엄격한 형식 적용 |
| 동시 쓰기 | Limited | 전체 동시성 지원 |
| 최대 연결 수 | 사실상 작성자 1명 | 많은 동시 연결을 사용하는 연결 풀링 |
DateTimeField |
텍스트로 저장 | datetimeoffset 또는 datetime2 |
데이터 정렬 차이점
데이터 정렬은 SQL Server 텍스트를 비교하고 정렬하는 방법을 제어합니다. 이는 PostgreSQL 또는 MySQL에서 마이그레이션할 때 예기치 않은 동작의 가장 일반적인 소스 중 하나입니다.
대/소문자 구분
SQL Server 기본 데이터 정렬(SQL_Latin1_General_CP1_CI_AS)은 대/소문자를 구분하지 않습니다. PostgreSQL은 기본적으로 대/소문자를 구분합니다.
이 동작은 마이그레이션 후에 이전에 구별된 "Smith" 쿼리를 "smith" 동일하게 처리한다는 것을 의미합니다.
# On PostgreSQL: returns only exact case matches
# On SQL Server (default collation): returns both "Smith" and "smith"
User.objects.filter(last_name="Smith")
애플리케이션이 대/소문자를 구분하는 비교에 의존하는 경우 다음 두 가지 옵션이 있습니다.
데이터베이스 또는 열 데이터 정렬 을 대/소문자를 구분하는 변형으로 변경합니다.
-- 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;대상 쿼리에 대해 원시 SQL에서 데이터 정렬 재정의와 함께 Django의
__exact조회를 사용합니다.
악센트 구분
기본 SQL Server 데이터 정렬은 PostgreSQL의 동작과 일치하는 악센트 구분(AS)입니다.
é 및 e와 같은 문자는 서로 다른 문자로 처리됩니다. 악센트를 구분하지 않는 비교가 필요한 경우 로 끝나는 _AI데이터 정렬을 사용합니다.
mssql-django에서 데이터 정렬 구성
데이터베이스 구성에서 텍스트 필드 조회에 대한 기본 데이터 정렬을 재정의합니다.
DATABASES = {
"default": {
"ENGINE": "mssql",
"NAME": "<your-database>",
"OPTIONS": {
"driver": "ODBC Driver 18 for SQL Server",
"collation": "Latin1_General_CS_AS", # Case-sensitive
},
},
}
메모
mssql-django의 collation 옵션은 Django의 ORM 조회가 생성하는 LIKE 및 비교 연산에서 사용되는 콜레이션을 제어합니다. 데이터베이스에 있는 기존 열의 데이터 정렬은 변경되지 않습니다. 저장된 열 데이터 정렬을 변경하려면 문을 사용합니다 ALTER TABLE / ALTER COLUMN . 자세한 내용은 SQL Server 데이터 정렬 설명서를 참조하세요.
4단계: 사용자 지정 SQL 업데이트
코드에 원시 SQL이 포함된 경우 SQL Server 구문으로 업데이트합니다.
# 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")
일반적인 SQL 구문 차이점:
| Operation | PostgreSQL/MySQL | SQL Server |
|---|---|---|
| 결과 제한 | LIMIT 10 |
TOP 10 또는 OFFSET ... FETCH NEXT ... |
| 문자열 연결 |
\|\| (PG) / CONCAT() |
+ 또는 CONCAT() |
| 부울 리터럴 | TRUE / FALSE |
1 / 0 |
| 현재 타임스탬프 | NOW() |
시간대 인식 값의 경우 GETDATE(), SYSDATETIME() 또는 SYSDATETIMEOFFSET() |
| 존재하지 않는 경우 | CREATE TABLE IF NOT EXISTS |
sys.objects 확인 또는 IF NOT EXISTS 사용 |
트랜잭션 격리 차이점
PostgreSQL은 격리 수준에 MVCC(다중 버전 동시성 제어)를 READ COMMITTED 사용합니다. 독자는 작성자를 막지 않으며, 작성자도 독자를 막지 않습니다.
SQL Server 기본값 READ COMMITTED 은 잠금을 사용합니다. 즉, 쓰기 트랜잭션이 완료되도록 기다리는 동안 읽기 쿼리가 차단할 수 있습니다. 마이그레이션 후 애플리케이션 차단이 증가하는 경우 데이터베이스에서 사용하도록 설정하는 것이 READ COMMITTED SNAPSHOT 좋습니다.
ALTER DATABASE [<your-database>]
SET READ_COMMITTED_SNAPSHOT ON;
이렇게 하면 SQL Server의 READ COMMITTED가 잠금 대신 행 버전 관리(PostgreSQL의 MVCC와 유사)를 사용하도록 변경됩니다. 읽는 사용자는 현재 쓰기 작업이 완료되기를 기다리지 않고도 행의 가장 최근에 커밋된 버전을 볼 수 있습니다.
메모
READ COMMITTED SNAPSHOT 에는 행 버전에 대한 추가 tempdb 공간이 필요합니다. 프로덕션 환경에서 사용하도록 설정하기 전에 실제 부하에서 테스트합니다. 자세한 내용은 mssql-django의 트랜잭션 관리를 참조하세요.
5단계: 데이터 마이그레이션
데이터 마이그레이션 전략은 데이터 세트 크기에 따라 달라집니다.
작은 데이터 세트(<500MB)
Django의 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
큰 데이터 세트(>500MB)
대규모 마이그레이션의 경우 특수 도구를 사용하여 메모리 소모 및 시간 제한 문제를 방지합니다. Django의 ORM은 이 규모에서 대량 로드에 적합한 도구가 아닙니다. 데이터 이동을 위해 이를 우회하고 Django에서 스키마 및 애플리케이션 논리를 나중에 관리할 수 있도록 합니다.
| Tool | 적합한 대상 |
|---|---|
| SQL Server 가져오기 및 내보내기 마법사 | GUI를 사용하여 온-프레미스에서 온-프레미스로 마이그레이션 |
| Azure Data Factory | 하이브리드 시나리오를 포함한 모든 원본에서 Azure SQL로 |
| Azure Database Migration Service | 기본 제공 유효성 검사 및 롤백을 사용하는 대규모 마이그레이션 |
| Apache 화살표를 사용하여 mssql-python 대량 복사 | Fabric SQL Server, Azure SQL Database 및 SQL 데이터베이스 간의 최대 처리량이 필요한 사용자 지정 Python 파이프라인 |
마이그레이션 후 유효성 검사
마이그레이션 후 자동 증가 열에 대한 ID 초기값 일관성의 유효성을 검사합니다.
-- 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;
CurrentIdentity이(가) IdentitySeed + record_count을(를) 초과하면, 다시 시드 설정:
DBCC CHECKIDENT ('your_table', RESEED, new_seed);