KeyError при чтении переменных окружения во время выполнения makemigrations в django

Контекст проблемы - я хочу мигрировать с базы данных SQLite на Postgres. Когда я makemigrations с настройками Postgres, которые передаются в файл настроек с переменными окружения, я получаю KeyError; однако другая переменная из того же файла не вызывает никаких проблем.

Мой секретный файл:

SECRET_KEY='secret key value'
DB_HOST='db host value'
DB_NAME='db name value'
DB_USER='db user value'
DB_PASS='db pass value'
DB_PORT='db port value'

Мои настройки dev.py:

from app.settings.base import *
import os
from dotenv import load_dotenv
import pprint

load_dotenv(os.environ.get('ENV_CONFIG', ''))

# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True

ALLOWED_HOSTS = ['*']

INSTALLED_APPS += [

]

MIDDLEWARE += [

]

env_var = os.environ
print("User's Environment variable:")
pprint.pprint(dict(env_var), width=1)

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.postgresql',
        'NAME': os.environ['DB_NAME'],
        'USER': os.environ['DB_USER'],
        'PASSWORD': os.environ['DB_PASS'],
        'HOST': os.environ['DB_HOST'],
        'PORT': os.environ['DB_PORT'],
    }
}

Как вы видите, я импортирую все содержимое из моего базового файла настроек - app.settings.base, где я использую свой секретный ключ (так же, как я читаю переменные окружения для базы данных):

SECRET_KEY = os.environ.get('SECRET_KEY', '')

Я использую SQLite в настройках моего base.py и хочу использовать Postgres в моем dev.py.

Однако, когда я пытаюсь ./manage.py makemigrations --settings=app.settings.dev, я получаю ошибку:

  File "/Users/admin/Desktop/Programming/Python/UkranianFunds/src/app/settings/dev.py", line 39, in <module>
    'NAME': os.environ['DB_NAME'],
  File "/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/os.py", line 679, in __getitem__
    raise KeyError(key) from None
KeyError: 'DB_NAME'

Но когда я печатаю все переменные окружения в dev.py вот так:

env_var = os.environ
print("User's Environment variable:")
pprint.pprint(dict(env_var), width=1)

Я вижу, что все мои переменные базы данных печатаются и значения правильные! То есть на уровне, когда я просто запускаю приложение, и вызывается печать - все переменные на месте. Но когда я делаю makemigrations - он не может найти ту же переменную по ключу.

Однако, когда я попытался установить настройки базы данных простым текстом (скопированным из файла .env) - все заработало.

Какая проблема может возникнуть при использовании переменных среды при выполнении makemigrations?

Я решил эту проблему, заменив os.environ['DB_NAME'] на os.environ.get('DB_NAME').

Но я не понимаю причины. Если ключа нет, os.environ.get вернет None, верно?

Если он не возвращает None, почему os.environ['DB_NAME'] выбрасывает исключение?

Когда вы используете метод os.environ.get('DB_NAME'), он не находит 'DB_NAME', а возвращает none.

То же самое касается и ваших настроек:

SECRET_KEY = os.environ.get('SECRET_KEY', '')

Если вы выводите секретный ключ, он будет пустым. Здесь вы просите получить секретный ключ, если он есть, иначе верните пустое место.

Первый вариант не работает, потому что вы используете словарь и просите словарь вернуть значение ключа. Если ключ не находится в словаре, то возвращается ошибка ключа:

os.environ['DB_NAME']

Вернуться на верх