Windows 10, Virtualenv, Django 2.0, Terminal and Setting Environment Variables

What I am doing currently

I use PyCharm's new project setup wizard to create Django projects. I set a virtualenv. In the virtualenv's activate.bat and deactivate.bat, I edit those manually to set environment variables for Django's settings.py : secret key, postgresql database name, postgresql database user, postgresql database password variables. For example, I am pulling these values out of the environment variables - 'NAME': os.environ['DATABASE_NAME'].

This approach works but whenever I open a project, the terminal conveniently activates the virtualenv (which I like) but doesn't load the environment variables so I just deactivate and activate again and they are loaded. Not a big deal but I'm wondering if I can do this without editing the venv activate.bat and deactivate.bat files and just use PyCharm's ability to set environment variables.

What I have tried

I'm not trying to set environment variables explicitly in the terminal : PyCharm, Virtualenv and Environment variables

I tried "Edit configurations" > Environment > Environment variables > ... > Name=DJANGO_SECRET_KEY, Value=<the random string with no quotes or anything> > Apply button > OK > in Terminal  : How to set environment variables in PyCharm?

(venv) C:\Users\jarad.collier\PycharmProjects\tdm>python manage.py runserver
Traceback (most recent call last):
File "manage.py", line 15, in <module>
execute_from_command_line(sys.argv)
File "C:\Users\jarad.collier\PycharmProjects\tdm\venv\lib\site-packages\django\core\management\__init__.py", line 371, in execute_from_command_line
utility.execute()
File "C:\Users\jarad.collier\PycharmProjects\tdm\venv\lib\site-packages\django\core\management\__init__.py", line 317, in execute
settings.INSTALLED_APPS
File "C:\Users\jarad.collier\PycharmProjects\tdm\venv\lib\site-packages\django\conf\__init__.py", line 56, in __getattr__
self._setup(name)
File "C:\Users\jarad.collier\PycharmProjects\tdm\venv\lib\site-packages\django\conf\__init__.py", line 43, in _setup
self._wrapped = Settings(settings_module)
File "C:\Users\jarad.collier\PycharmProjects\tdm\venv\lib\site-packages\django\conf\__init__.py", line 106, in __init__
mod = importlib.import_module(self.SETTINGS_MODULE)
File "C:\python36\lib\importlib\__init__.py", line 126, in import_module
return _bootstrap._gcd_import(name[level:], package, level)
File "<frozen importlib._bootstrap>", line 994, in _gcd_import
File "<frozen importlib._bootstrap>", line 971, in _find_and_load
File "<frozen importlib._bootstrap>", line 955, in _find_and_load_unlocked
File "<frozen importlib._bootstrap>", line 665, in _load_unlocked
File "<frozen importlib._bootstrap_external>", line 678, in exec_module
File "<frozen importlib._bootstrap>", line 219, in _call_with_frames_removed
File "C:\Users\jarad.collier\PycharmProjects\tdm\tdm\settings.py", line 23, in <module>
SECRET_KEY = os.environ['DJANGO_SECRET_KEY']
File "C:\python36\lib\os.py", line 669, in __getitem__
raise KeyError(key) from None
KeyError: 'DJANGO_SECRET_KEY'

Since that didn't work, I tried various other methods illustrated here: Pycharm: set environment variable for run manage.py Task

Take-aways from that are that I can set environment variables in several places!

  • File > Settings > Build, Execution, Deployment > Console > Python Console or Django Console
  • File > Settings > Languages & Frameworks > Django > Manage.py tasks
  • Edit configurations area (already mentioned)

What I want to be able to do

Very specifically, I want to set environment variables within PyCharm to hide secret things (secret key, database info) in the environment itself. Then I want to be able to run "python manage.py runserver" very specifically within the "Terminal" that's inside PyCharm and have it run without throwing KeyError (because it finds the variables).

Where and how within PyCharm can I do this?

Note: I'm not really interested in alternative methods like storing an external file somewhere or having an external script set these variables. I REALLY want to be able to do this within PyCharm and to understand the process and what I'm doing wrong!

Thank you

9 comments

*Adele voice* Helloooo.... It's me. I was wondering if after all these days you'd like to read.

Seriously though, I'd love to get a PyCharm pro's answer on this one, if possible. I know you all are super-busy so if not, I understand.

0

This is EXACTLY what I want too. 

Does anyone have any suggestion on how to do it?

 

0

Hi,

This may be a long shot, but you've mentioned that you're running 'manage.py' tasks from terminal, so have you tried setting variables in File | Settings | Tools | Terminal ?

Otherwise, if you set them in File | Settings | Languages & Frameworks | Django , have you tried running with Tools > Run manage.py task... ? Do you still get the same error this way?

0

Hi Andrey,

Thanks for the suggestion.

No matter how you do it it seems you have to set the Environment Variables in multiple places, which is what I'm trying to avoid.

If I use the Run Manage.py task it has it's own Env Vars distinct from the Run Configuration, the Terminal has it's own set again.

I've seen all sorts of suggestions but they all come back to this issue.

It seems such an obvious issue I was hoping there was a kind of official solution that I was missing.

The only suggestions I've seen that kind of work feel very hacky, like activating the Virtual Env and only running PyCharm from the Terminal.

Or using code to load env variables from a file.

It just seems to come down to the fact that each task, run configuration, terminal etc, runs in it's own environment.

 

 

0

I agree 100% with the comment that there should be an "official" solution to this very common question.

I remember giving up on this because there were so many places in PyCharm to set environment variables and I feel like I tried them all and none of them worked.

I ultimately ended up setting the environment variables in virtualenv's activate.bat file.

For example, the file usually starts with @echo off:

@echo off
set "VIRTUAL_ENV=C:\Users\Jarad\Documents\PyCharm\coursenode_project\venv"
set "SECRET_KEY=oh6*p5ku)b3zvxsv@5e4326ghg9h=n)4zjeor^^^03*%e_^)o15-@-9"
set "DEBUG_MODE=True"
set "ALLOWED_HOST=127.0.0.1"
set "DB_NAME=somename"
set "DB_USER=jarad"
set "DB_PASSWORD=abc123"
set "DB_HOST=127.0.0.1"
set "DB_PORT=5432"

if defined _OLD_VIRTUAL_PROMPT (
set "PROMPT=%_OLD_VIRTUAL_PROMPT%"
... 

Then you use these environment variables using the os.environ.get('KEY_GOES_HERE'). For example, if I wanted to grab the value of the DB_NAME, I would os.environ.get('DB_NAME') in my Django settings folder to set the database name.

0

Yeah, I tried activate.bat, but I don't think even that works for all the different ways PyCharm runs things.

0

PyCharm is aware of any variable in the environment from which you start it, but, unfortunately, there is no way to set environment variables globally for the whole PyCharm IDE using GUI.

You can use any of the methods to set environmet variables prior to launching PyCharm: setting them in virtualenv activation script, setting them in your .bashrc (restart session to source .bashrc), or rc.local, or export them using .sh script, there are many ways.

0

Hi Andrey,

I'm aware of that trick, I've seen it suggested on Stackoverflow. But I've never considered it a satisfactory solution.

Just on a simple level, I can't run the IDE from the toolbox or from the Start Menu or Dock.

I can't close a project and open a different one without completely closing the IDE, activating a different venv and starting the IDE again.

I like paying for tools so I don't have to do stuff like this. It's not like virtual environments are a niche edge case in Python.

I believe there's work happening on a ticket that might be a solution. I'm signed up until November anyway so I'll see how it pans out.

0

Richard,

I understand what you want to do. It might be inconvenient to set the env variables in different places for each tool (run conf, python console, e.t.c) but once you do, it is saved in this project, you don't have to do it each time (unless your env variables are changing often, in which case maybe they're not the best place to store things like database credentials?).

But I agree setting them globally might be a useful feature. Do you have a link to the ticket you're referring to? If it's a YouTrack ticket, I'll leave my vote over there.

0

Please sign in to leave a comment.