반응형
Django에서 ReplicaDB (ReadonlyDB)가 있을 때 테스트 코드를 작성하면 다음과 같은 문제가 발생할 수 있습니다. 분명 데이터베이스 쓰기에 성공했는데, 해당 데이터를 읽어보면 데이터가 없는 경우가 있습니다. 데이터를 default DB에 입력했는데, 읽는 것은 readonly DB에서 읽으려고 해서 해당 문제가 발생합니다. 테스트 코드를 작성하는 상황에서는 보통 로컬에서 DB를 생성하기 때문에 replica DB를 따로 사용하지 않을 가능성이 크기 때문입니다.
Django의 공식문서를 확인하면 replicaDB에 대해서는 MIRROR를 default
DB로 설정하여 replica DB에 대해서 DB생성을 막는 방법을 알려줍니다.
아래는 Django 공식문서의 예제입니다.
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'myproject',
'HOST': 'dbprimary',
# ... plus some other settings
},
'replica': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'myproject',
'HOST': 'dbreplica',
'TEST': {
'MIRROR': 'default',
},
# ... plus some other settings
}
}
하지만, 이렇게 해도 replica DB가 생성되지 않을 뿐, 여전한 문제가 발생했습니다. (만약 이렇게 해서 해결된다면 다음 내용은 지나치셔도 됩니다.) 몇 시간 삽질을 해보니 해당 문제는 아주 오래된 Django의 이슈임을 확인했습니다.
해당문제는 여전히 connections["replica"]가 replica DB에 접근하려고 해서 생기는 문제입니다. 이는 Django의 테스트케이스를 오버라이딩해서 해결할 수 있습니다.
# utils/test.py
from django.test import TestCase
class BaseTestCase(TestCase):
databases = ["default", "replica"]
@classmethod
def setUpClass(cls):
connections["replica"]._orig_cursor = connections["replica"].cursor
connections["replica"].cursor = connections["default"].cursor
super().setUpClass()
@classmethod
def tearDownClass(cls):
connections["replica"].cursor = connections["replica"]._orig_cursor
super().tearDownClass()
- 테스트케이스를 시작하기 전에
replica
의 cursor를default
의 cursor로 바꿔줍니다. - 테스트케이스가 끝나면 다시
replica
의 cursor를 원래대로 돌려줍니다. - Django 2.2부터 Multiple Database (Replica DB 포함)를 쓸 때는
databases = "__all__"
또는 관련 있는 데이터베이스들을 모두 명시해 주어야 합니다. (databases = ["default", "replica"]
)
이제 해당 클래스를 대신 import해서 기존의 문제를 해결할 수 있습니다.
# someapp/test.py
from utils.test import BaseTestCase
class SomeTestCase(BaseTestCase):
"""
...
Test code goes here
...
"""
반응형
'개발 > 파이썬' 카테고리의 다른 글
자주쓰는 명령어로 배우는 Pandas #2 : Index와 Column 조작하기 (0) | 2020.10.25 |
---|---|
자주쓰는 명령어로 배우는 Pandas #1 : Pandas와 데이터 살펴보기 (0) | 2020.10.24 |
Django ELB ALLOWED HOSTS 에러 수정 (0) | 2020.06.20 |
프로그래밍 폴더 구조에 대한 생각정리 (4) | 2020.06.18 |
[TIL] JWT 로그인 구현과 보안 (0) | 2020.06.10 |