Context of the problem – I want to migrate from the SQLite database to Postgres.
When I makemigrations
with Postgres settings which are passed to the settings file with environment variables, I get KeyError; however, another variable from the same file does not cause any problems.
My secrets file:
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'
My dev.py settings:
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'],
}
}
As you see, I import all the content from my base settings file – app.settings.base, where I use my secret key (in the same way as I read my environment variables for database):
SECRET_KEY = os.environ.get('SECRET_KEY', '')
I use SQLite in my base.py settings and want to use Postgres in my dev.py.
However, when I try to ./manage.py makemigrations --settings=app.settings.dev
, I get the error:
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'
But when I print all the environment variables in dev.py like this:
env_var = os.environ
print("User's Environment variable:")
pprint.pprint(dict(env_var), width=1)
I see that all my database variables are being printed and the values are correct!
So on the level when I just run the app, and print being called – all the variables are there.
But when I do makemigrations
– it couldn’t find the same variable by key.
However, when I tried to set database settings with just plain text (copied from .env file) – everything worked.
What could be an issue in using environment variables when doing makemigrations
?
2
Answers
I solved it by replacing
os.environ['DB_NAME']
toos.environ.get('DB_NAME')
.But I don't understand the reason. If the key is not there,
os.environ.get
will returnNone
, right?If it doesn't return None, why
os.environ['DB_NAME']
throws an exception?When you are using the
os.environ.get('DB_NAME')
method then it is not finding the ‘DB_NAME’ but returns a none.Same goes with you settings:
SECRET_KEY = os.environ.get('SECRET_KEY', '')
If you print the secret key it will be empty. Here you are asking to get secret key if it is there otherwise return an empty space.
The first one is not working because you are using a dictionary and asking the dictionary to return the value of the key. If the key is not in the dict then it returns key error:
os.environ['DB_NAME']