오늘도 개발

django에 데이터베이스 여러 개 연결하기 본문

웹 프로그래밍/Django

django에 데이터베이스 여러 개 연결하기

Sueeeeeee 2023. 2. 18. 17:30

세팅

한 장고 프로젝트에 여러 데이터베이스(프로덕션, 개발용 등)를 연결시키고 싶은 경우,
settings.py의 DATABASES 딕셔너리에 추가해서 사용할 수 있다.
각 데이터베이스의 alias를 키로 사용한다.

# default, users, customers 데이터베이스를 프로젝트와 연결하는 경우
DATABASES = {
   'default' : {},
   'production' : {
      'NAME' : 'production_data',
      'ENGINE' : ...
   },
   'develop' : {
       ...
   }
}
using을 사용하면 어떤 데이터베이스를 사용할 것인지 명시할 수 있다.
# alias가 users인 db에서 쿼리 수행
Deal.objects.using('users').filter()

 

라우팅

어떤 모델을 default가 아닌 데이터베이스와 연결하려면 라우터를 설정해주어야 한다.
따로 라우터가 없는 모델은 위에서 작성한 DATABASES 딕셔너리의 default를 데이터베이스로 사용한다.

 

Database Router 클래스는 네 가지 메서드를 제공한다.
메서드를 사용하여 각 모델이 어느 db에서 어떤 작업을 할 수 있도록 허용할 지 정해줄 수 있다.

# routers.py

class UserRouter:    
    target_models = ('PhoneNumber', 'Email')

    def db_for_read(self, model, **hints):
        # 위 2개 모델은 alias가 user인 데이터베이스에서 읽기 작업을 하도록 설정
        if model.__name__ in self.target_models:
            return 'user'
        return None

    def db_for_write(self, model, **hints):
        # 위 2개 모델은 alias가 user인 데이터베이스에서 쓰기 작업을 하도록 설정
        if model.__name__ in self.target_models:
            return 'user'
        return None

    def allow_relation(self, obj1, obj2, **hints):
        # 위 2개 모델은 alias가 user인 데이터베이스 외의 모델을 참조하거나 참조될 수 없게 설정
        return None

    def allow_migrate(self, db, app_label, model_name=None, **hints):
        # 위 2개 모델은 alias가 user인 db에만 마이그레이션 되지 않도록 설정
        if db == 'user':
            return True
        return None

 

특정 데이터베이스에 마이그레이션하기

python manage.py [app] --database [데이터베이스 alias]
# python manage.py contacts --database user

 

특정 데이터베이스에서 SQL 실행하기

# 사용하는 db가 하나인 경우
from django.db import connection

with connection.cursor() as cursor:
   cursor.execute("SELECT id FROM users")
   ids = cursor.fetchall() # 결과가 여러 row인 경우 fetchall
   
   cursor.execute("SELECT id FROM users WHERE name = snoopy")
   id = cursor.fetchone() # 결과가 하나인 경우 fetchone
여러 개의 db 중 하나를 사용할 경우
from django.db import connections

users_db = db.connections['users']
with users_db.cursor() as cursor:
   ...