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']