큰 프로젝트를 구현하다 보면 한 프로젝트 내에서 여러 데이터베이스와 연결하는 경우가 많다. 기본적으로는 django documents 사이트에 나와있듯이 settings 에 사용할 데이터베이스 정보를 추가해 놓고 using() 을 사용하거나 router.py 파일을 추가하여 데이터베이스에 연결하는 방법이 있다. 하지만, 셀 수 없이 많은 데이터베이스에 다이나믹하게 연결해야 하는 경우는 위와 같은 방식으로 사용하면 안된다. 이 페이지에는 장고 프로젝트에서 다이나믹하게 데이터베이스에 접근하는 방법에 대해 설명할 것이다.
데이터베이스 연결 방법
from django.db import connections
external_db = {
'ENGINE': 'django.db.backends.postgresql_psycopg2',
'NAME': 'db_name',
'USER': 'user_name',
'PASSWORD': 'password',
'HOST': '127.0.0.1',
'PORT': '5432',
# DB 스키마 사용시 추가
'OPTIONS': {
'options': '-c search_path=schema_name'
},
}
# DB 연결
connections.databases['db_key'] = external_db
일단 기본적으로 데이터베이스를 다이나믹하게 연결하는 방법은 위와 같다. 기본적인 구현 방법은 같으나, API 를 구현할 때 함수 방식과 클래스 방식 두 가지 방식으로 구현이 가능하기 때문에 나눠서 설명하겠다.
먼저, models.py에 테스트를 위한 model 을 추가해 주고 django-rest-framework 라이브러리를 설치해 준다.
함수(def) 방식
from django.core import serializers
from django.db import connections
from django.http JsonResponse
from rest_framework.decorators import api_view
from rest_framework.response import Response
from .models import TestTable
@api_view(['GET])
def test(request):
db_name = request.query_params.get('db_name', None)
schema = request.query_params.get('schema', None)
if db_name and schema:
external_db = {
'ENGINE': 'django.db.backends.postgresql_psycopg2',
'NAME': db_name,
'USER': 'user_name',
'PASSWORD': 'password',
'HOST': '127.0.0.1',
'PORT': '5432',
# DB 스키마 사용시 추가
'OPTIONS': {
'options': '-c search_path=' + schema
},
}
# DB 연결
connections.databases[db_name] = external_db
# 데이터 조회
test = TestTable.objects.using(db_name).all()
return JsonResponse(serializers.serializer('json', test), safe=False)
return Response({})
다이나믹하게 접근하기 위해 파라미터로 db_name, schema 정보를 받았고 두 개의 파라미터를 잘 받았을 시에 테이블의 모든 데이터를 조회해온다.
클래스(class) 방식
from django.db import connections
from rest_framework.viewsets import ReadOnlyModelViewSet
from .models import TestTable
from .serializers import TradeSerializer
class TestViewSet(ReadOnlyModelViewSet):
queryset = TestTable.objects.all()
def get_serializer_class(self):
return TestSerializer
def get_queryset(self):
db_name = request.query_params.get('db_name', None)
schema = request.query_params.get('schema', None)
if db_name and schema:
external_db = {
'ENGINE': 'django.db.backends.postgresql_psycopg2',
'NAME': db_name,
'USER': 'user_name',
'PASSWORD': 'password',
'HOST': '127.0.0.1',
'PORT': '5432',
# DB 스키마 사용시 추가
'OPTIONS': {
'options': '-c search_path=' + schema
},
}
# DB 연결
connections.databases[db_name] = external_db
# 데이터 조회
return TestTable.objects.using(db_name).all()
return TestTable.objects.all()
def list(self, request, *args, **kwargs):
return super(TestViewSet, self).list(request, *args, **kwargs)
class 형식을 사용할 때는 queryset 을 받아오는 함수인 get_queryset() 를 추가해 줘야 한다.
'Python > Django' 카테고리의 다른 글
[Django] tuple' object has no attribute '_meta' (0) | 2016.12.22 |
---|---|
[Django] settings.py 분리하기 (0) | 2016.11.16 |
[Django] django-crontab (0) | 2016.10.28 |
[Django] values() values_list() flat (0) | 2016.10.26 |
[Django] File upload (FileField, ImageField) (0) | 2016.10.19 |
댓글