PostgreSQL 다른 스키마를 Django에서 활용하는 방법

PostgreSQL에서는 기본적으로 public 스키마가 제공되며, Django 역시 기본적으로 이 public 스키마를 사용합니다. 그러나 프로젝트의 요구사항에 따라 다른 스키마를 사용해야 할 때가 있습니다. 이 글에서는 PostgreSQL에서 public 외의 다른 스키마를 Django와 함께 사용하는 방법과 설정 시 주의해야 할 점들을 정리해보겠습니다.

인프런 질문

인프런 파이썬/장고 웹서비스 개발 완벽 가이드 with 리액트 (장고 4.2 기준) 강의에서 pytest 코드 실행 오류 질문을 받았습니다. 테스트 시에만 다른 데이터베이스 schema를 지정하는 부분에 대한 질문이 있어서, 이에 대해서 간략히 정리해봅니다.

PostgreSQL 스키마와 Django의 기본 동작

  1. PostgreSQL은 여러 스키마(schema)를 지원하며, 스키마를 통해 테이블을 논리적으로 그룹화할 수 있습니다.
  2. Django는 기본적으로 PostgreSQL의 public 스키마를 사용하며, 별다른 설정 없이도 모든 테이블이 여기에 생성됩니다.
  3. Django의 마이그레이션 기능에서는 스키마를 자동으로 생성하지 않습니다. 마이그레이션 과정에서 지정 스키마가 없을 경우 CREATE TABLE 쿼리 수행 시에 psycopg2.errors.InvalidSchemaName 예외가 발생합니다.

다른 스키마를 사용하도록 설정하기

Django 프로젝트에서 다른 스키마를 사용하려면 DATABASES 설정에 search_path를 추가해야 합니다. 아래와 같이 settings.py에 설정합니다:

DATABASES = {
    "default": {
        "ENGINE": "django.db.backends.postgresql",
        "NAME": "your_database_name",
        "USER": "your_username",
        "PASSWORD": "your_password",
        "HOST": "localhost",
        "PORT": "5432",
        "OPTIONS": {
            "options": "-c search_path=other_schema"
        },
    }
}

여기에서 other_schema는 사용할 스키마 이름입니다. 생략하면 public 스키마로 접근합니다. 지정한 스키마가 지정 데이터베이스에 없다면 마이그레이션 과정에서 아래 오류가 발생합니다. 테스트 시에도 자동 마이그레이션 과정에서 해당 오류가 발생합니다.

psycopg2.errors.InvalidSchemaName: no schema has been selected to create in
LINE 1: CREATE TABLE "django_migrations" ("id" bigint NOT NULL PRIMA...

지정한 스키마를 반드시 데이터베이스 서버에서 먼저 생성해주셔야 합니다.

동적으로 스키마를 지정하기

장고 구동환경에 따라 사용할 스키마를 동적으로 지정하고 싶다면, 아래와 같이 설정하실 수 있습니다.

import os
from environs import Env

env = Env()
env.read_env(overwrite=True)  # .env 파일 로드

DEFAULT_DATABASE_URL = f"sqlite:///{BASE_DIR / 'db.sqlite3'}"
DATABASES = { "default": env.db(default=DEFAULT_DATABASE_URL) }

# 추가한 부분
DATABASE_SCHEMA = env.str("DATABASE_SCHEMA", default=None)
if DATABASE_SCHEMA:
    DATABASES["default"]["OPTIONS"] = { "options": f"-c search_path={DATABASE_SCHEMA}" }

테스트 시에도 DATABASE_SCHEMA 환경변수를 지정하여 원하는 스키마에서 테스트가 수행되도록 하실 수 있습니다.

DATABASE_SCHEMA=other_schema

pytest와 환경변수

pytest 환경에서 환경변수를 지정할려면 pytest-env 라이브러리를 설치해야만 합니다. 설치 후에 pytest.ini 파일에 다음과 같이 테스트에서 사용할 환경변수를 지정하실 수 있습니다.

[pytest]
env =
    DATABASE_SCHEMA=other_schema

pytest-env를 통한 환경변수 지정은 장고 프로세스가 시작되기 전에 환경변수를 주입합니다. 그런데 장고 프로세스 내에서 .env 로딩하여 환경변수를 설정할 때 env.read_env(overwrite=True) 코드가 있다면, 같은 이름의 환경변수를 덮어쓸 수도 있으니 주의해주세요.

정리

  • PostgreSQL의 public 스키마 대신 다른 스키마를 사용하려면 OPTIONS{"options": "-c search_path=스키마명"} 설정이 필요합니다.
  • 설정한 스키마가 존재하지 않으면 오류가 발생하므로 스키마를 먼저 생성해야 합니다.
  • 실행 환경에 따라 동적으로 스키마를 지정하려면 환경변수를 활용하세요.
  • Pytest를 사용할 경우 pytest-env를 이용해 테스트 환경에서만 사용할 환경변수를 지정하실 수 있습니다.

위의 방법을 활용하면 Django에서 더 유연하게 PostgreSQL 스키마를 관리할 수 있습니다.

  • 마지막 편집일시 : 2024년 12월 17일 11:49 오전
  • 최초 생성일시 : 2024년 12월 17일 11:37 오전
🌟 본 포스팅이 도움이 되셨다면 댓글 하나 남겨주시고, 널리 공유도 부탁드립니다. 🌟

댓글