PostgreSQL에서는 기본적으로 public 스키마가 제공되며, Django 역시 기본적으로 이 public 스키마를 사용합니다. 그러나 프로젝트의 요구사항에 따라 다른 스키마를 사용해야 할 때가 있습니다. 이 글에서는 PostgreSQL에서 public 외의 다른 스키마를 Django와 함께 사용하는 방법과 설정 시 주의해야 할 점들을 정리해보겠습니다.
인프런 파이썬/장고 웹서비스 개발 완벽 가이드 with 리액트 (장고 4.2 기준) 강의에서 pytest 코드 실행 오류 질문을 받았습니다. 테스트 시에만 다른 데이터베이스 schema를 지정하는 부분에 대한 질문이 있어서, 이에 대해서 간략히 정리해봅니다.
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-env 라이브러리를 설치해야만 합니다. 설치 후에 pytest.ini 파일에 다음과 같이 테스트에서 사용할 환경변수를 지정하실 수 있습니다.
[pytest]
env =
DATABASE_SCHEMA=other_schema
pytest-env를 통한 환경변수 지정은 장고 프로세스가 시작되기 전에 환경변수를 주입합니다. 그런데 장고 프로세스 내에서 .env 로딩하여 환경변수를 설정할 때 env.read_env(overwrite=True) 코드가 있다면, 같은 이름의 환경변수를 덮어쓸 수도 있으니 주의해주세요.
OPTIONS에 {"options": "-c search_path=스키마명"} 설정이 필요합니다.pytest-env를 이용해 테스트 환경에서만 사용할 환경변수를 지정하실 수 있습니다.위의 방법을 활용하면 Django에서 더 유연하게 PostgreSQL 스키마를 관리할 수 있습니다.
댓글