Django를 사용해 웹 애플리케이션을 개발할 때, 데이터베이스의 구조를 유지하고 변경하는 것은 매우 중요하다. 마이그레이션은 데이터베이스 테이블을 생성, 수정, 삭제하는 과정을 자동화하는 기능으로, 이 기초적인 부분을 잘만 이해해 놓는다면 개발할 때 매우 편할 것이다. 따라서 이번 글에서는 Django에서 마이그레이션과 같이 알아두면 좋은 개념들(Sqlite, 마이그레이션, 마이그레이션 롤백,Django Shell 등), MySQL을 Django 프로젝트에 연동하는 과정을 설명하려 한다.
Django Migration이란?
마이그레이션(migration)은 Django에서 데이터베이스의 스키마(구조)를 관리하고 변경하는 방법이다. 데이터베이스 테이블을 생성, 수정, 삭제하는 과정을 자동화해 준다.
Django에서는 모델(model) 파일을 기반으로 데이터베이스에 반영할 수 있는 파일을 생성하고, 이를 통해 실제 데이터베이스에 적용하는 방식이다.
초기 마이그레이션 (python manage.py migrate)
Django 프로젝트를 생성하고 python manage.py runserver를 실행하면 위 사진과 같이 db.sqlite3 파일이 생성된다. settings.py에 설정된 데이터베이스 엔진에 따라 자동으로 생성되는 파일이다. 이후 python manage.py migrate를 처음 실행하면, settings.py에 설정된 데이터베이스 엔진에 따라 기본적으로 필요한 테이블들이 생성된다.
python manage.py migrate
- settings.py의 DATABASES 설정에 따라 데이터베이스에 연결한다. 기본으로 sqlite가 설정되어 있다.
- Django의 기본 앱(admin, auth, contenttypes, sessions)에 필요한 테이블을 생성한다.
기존에 db.sqlite에 아무것도 없었다면 초기 마이그레이션을 해주고 나면 아래 사진과 같이 Django 기본 앱에 필요한 테이블들이 생성되는 것을 볼 수 있다.
VSCode에서 SQLite 데이터베이스 확인하기
초기 세팅으로 Django는 SQLite이 사용된다. VSCode에서 데이터베이스를 직접 확인하려면 SQLite 확장 프로그램을 설치하면 된다.
.db 파일(예: db.sqlite3)을 우클릭해서 Open Database를 누르면 데이터베이스의 테이블과 데이터를 시각적으로 확인할 수 있다.
위와 같이 탐색기 아래에 SQLITE EXPLORER에 존재하는 테이블들을 확인할 수 있다. 현재는 Django 기본 앱에 필요한 테이블들(각 필드들 까지)이 생성된 것을 볼 수 있다. 가장 흔히 쓰는 User 내장 모델도 확인할 수 있다.
터미널에서 SQLite 데이터베이스 확인하기
물론 SQLite 데이터베이스를 터미널에서 직접 확인할 수도 있다.
SQLite3 CLI 실행
sqlite3 db.sqlite3
데이터베이스의 모든 테이블 보기
.tables
특정 테이블의 스키마 보기
.schema <table_name>
데이터 조회
SELECT * FROM <table_name>;
종료
.quit
마이그레이션 파일 생성 (python manage.py makemigrations)
새로운 모델을 정의하거나 기존 모델을 수정했을 때, 데이터베이스에 적용하기 전 마이그레이션 파일을 먼저 생성해야 한다.
python manage.py makemigrations
- migrations 폴더에 .py 확장자를 가진 마이그레이션 파일이 생성된다.
- 이 파일은 데이터베이스에 적용할 변경사항을 설명하는 코드이다.
class Posts(models.Model):
title = models.TextField(max_length=30)
content = models.TextField(max_length=100)
cnt = models.IntegerField(default=0)
만약 models.py에 위와 같은 코드를 저장하고, python manage.py makemigrations 명령어로 마이그레이션 파일 생성한다. users/migrations/0001_initial.py 파일이 생성되며, 해당 파일에서 데이터베이스에 적용될 변경사항을 확인할 수 있다.
추가로 Posts에 cnt = models.IntegerField(default=0) 필드를 추가해 준 뒤 python manage.py makemigrations를 진행해 준다면 다음과 같은 결과가 나타난다.
처음 결과와 동일하게 변경 사항이 터미널에서도 보이고, 생성된 파일에서도 확인할 수 있다.
class Posts(models.Model):
title = models.TextField(max_length=30)
content = models.TextField(max_length=100)
cnt = models.IntegerField(default=0)
author = models.TextField(max_length=30, default='')
date = models.DateField(default=datetime.now())
class News(models.Model):
title = models.TextField(max_length=30)
content = models.TextField(max_length=100)
class Comment(models.Model):
title = models.TextField(max_length=30)
content = models.TextField(max_length=100)
models.py을 다음과 같이 바꾸고, makemigrations 명령어를 치면 아래와 같이 나온다. 이처럼 Model 생성과, Field 추가를 터미널로 확인할 수 있다.
마이그레이션 SQL 미리 보기(python manage.py sqlmigrate app_name migration_name)
마이그레이션이 데이터베이스에 적용될 SQL 쿼리를 미리 보려면 다음 명령어를 사용한다.
python manage.py sqlmigrate app_name migration_name
이 명령어는 마이그레이션 파일을 SQL 쿼리로 변환하여 보여준다.
데이터베이스에 마이그레이션 적용 (python manage.py migrate)
마이그레이션 파일을 생성한 후, 데이터베이스에 적용하려면 python manage.py migrate를 실행한다.
python manage.py migrate
결과는
Applying users.0001_initial... OK
Applying users.0002_posts_cnt... OK
Applying users.0003_comment_news_posts_author_posts_date... OK 가 터미널에 뜬다면 마이그레이션이 정상적으로 데이터베이스에 적용되었음을 확인할 수 있다.
마이그레이션 롤백 (취소 및 이전 버전으로 되돌리기)
개발을 진행하다 보면, 데이터베이스 모델을 수정하는 과정에서 마이그레이션 파일이 꼬이거나 예상치 못한 문제가 발생할 수 있다. 이러한 경우 당황하지 말고, 이전 상태로 되돌리기 위해 마이그레이션 롤백을 사용하면 된다.
특정 마이그레이션으로 롤백
python manage.py migrate app_name migration_name
이 명령어는 지정한 마이그레이션 상태로 데이터베이스를 되돌린다. 예를 들어, python manage.py migrate myapp 0001을 실행하면 0001_initial.py 마이그레이션 파일의 상태로 데이터베이스가 되돌아간다.
만약 0001_initial 상태로 데이터베이스를 완벽히 되돌리고 싶다면, 해당 명령어 실행 후 0002, 0003 등의 이후 마이그레이션 파일을 삭제하고, models.py를 0001_initial.py에 맞게 수정하면 된다.
마지막 마이그레이션 되돌리기
python manage.py migrate app_name zero
해당 명령어는 모든 마이그레이션을 취소하고, 데이터베이스의 해당 앱과 관련된 테이블을 완전히 삭제한다. 따라서 사용 전에 백업을 권장한다.
Django Shell을 활용한 데이터베이스 확인
Django Shell은 view를 작성하지 않고도 터미널에서 Django 환경을 직접 실행하여 데이터베이스를 확인하고 조작할 수 있는 강력한 도구이다.
Django Shell 실행
python manage.py shell
데이터를 생성하는 예제
from users.models import Posts
# 새로운 Post 객체 생성
test_post = Posts(title="My First Post", content="This is a test content", cnt=1)
# 데이터베이스에 저장
test_post.save()
이처럼 Django Shell을 사용하면 데이터베이스에 직접 접근하고, 쿼리를 실행하거나 데이터를 추가 및 삭제할 수 있다.
데이터베이스 조회 예제
Posts.objects.all()
이 코드는 Posts 모델의 모든 데이터를 조회하는 예제이다.
데이터를 수정하는 예제
# 특정 Post 객체 가져와서 cnt 필드 값 수정
post = Posts.objects.get(id=1)
post.cnt = 5
post.save()
데이터를 삭제하는 예제
# 특정 Post 객체 삭제
post.delete()
이처럼 Django Shell을 사용하면 데이터베이스에 직접 접근하고, 쿼리를 실행하거나 데이터를 추가, 수정, 삭제할 수 있다.

MySQL 사용하기 (Mac 기준)
Django는 기본적으로 SQLite 데이터베이스를 내장하고 있어, 별도의 데이터베이스 설정 없이 `settings.py`의 기본 설정만으로 간편하게 사용할 수 있다. 하지만 EC2와 같은 서버에 배포할 때, 데이터베이스와 서비스 서버가 같은 인스턴스에 존재하는 경우 트래픽이 많아지면 성능 저하가 발생할 수 있다. 또한, 서버 장애가 발생하면 데이터베이스와 서비스가 동시에 손실될 위험도 존재한다.
따라서 소규모 프로젝트에서는 SQLite로도 충분하지만, 안정성과 확장성을 고려한 서비스에서는 별도 데이터베이스를 사용하는 것이 좋다.
나는 가장 많이 접해봤을 MySQL로 실습을 진행했다.
1. MySQL 설치 및 설정 (Mac)
brew install mysql
brew services start mysql
mysql -u root -p
2. 데이터베이스 생성
CREATE DATABASE django_test1;
사용자까지 따로 만들어서 해볼 수 있지만 나는 그냥 root 사용자를 이용해서 실습했다.
3. Django settings.py 설정
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'django_test1', # 사용할 MySQL 데이터베이스 이름
'USER': 'root', # MySQL 사용자명 (root)
'PASSWORD': '비밀번호', # MySQL root 비밀번호
'HOST': 'localhost', # MySQL 서버 주소 (로컬 사용시 localhost)
'PORT': '3306', # MySQL 기본 포트
}
}
4. MySQL 클라이언트 설치 및 마이그레이션 실행
pip install mysqlclient
python manage.py makemigrations
python manage.py migrate
테이블이 데이터베이스에 생성된 것을 MySQL에서 직접 확인할 수 있다.
USE django_test1;
SHOW TABLES;
마무리
사실 나도 Django를 배우고 나서 DB 설정을 따로 한 적이 없다. (개발 입문 당시만 Django를 사용했고, 이후에는 Spring을 공부했다. 그래서 Django는 여전히 내 개발 입문에서 멈춰있는 느낌이 강했기 때문에, 이번 자료를 준비하면서 더 깊이 공부할 수 있었다.)
Django를 처음 사용할 때는 왜 데이터베이스를 따로 설정해야 하는지, 어떤 장단점이 있는지 깊게 생각하지 않고, 기본 제공되는 SQLite만 사용했었다. 사실 생각을 안 한 게 아니라, 그때는 몰랐다. 당시엔 모든 서버 프레임워크가 데이터베이스를 자동으로 연결해 주는 줄 알았다... 단순히 제공되는 환경에서 CRUD 기능만 개발했고, 마이그레이션 오류가 발생하면 원인을 분석하기보다는 프로젝트를 삭제하고 처음부터 다시 시작했던 경험이 많았다.
이제서야 데이터베이스를 직접 설정하고 관리하는 것이 왜 중요한지 이해하게 되었고, 이러한 경험을 바탕으로 Django의 마이그레이션과 관련한 기초 개념들을 정리해 보았다.
'Django' 카테고리의 다른 글
[Django] Django 프로세스, Request-Response Lifecycle (Web Server, WSGI/ASGI, Middlewares, Django) (1) | 2025.01.24 |
---|---|
[Django] URL dispatcher 공식 문서 파헤치기 (1) | 2025.01.18 |
[Django] settings.py 완전 정복 (..파일 분리까지) (0) | 2025.01.11 |
[Django] User Model, Custom User (Extending User) (0) | 2025.01.11 |
[Django] Django란? + 기초 실습 (1) | 2025.01.04 |