Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

can not override environment settings that already have value with a file #103

Closed
bmoelans opened this issue Jan 3, 2017 · 13 comments
Closed
Assignees
Labels
bug Something isn't working

Comments

@bmoelans
Copy link

bmoelans commented Jan 3, 2017

I have

env = environ.Env(
    DEBUG=(bool, False),
)
ENV_FILE = str(env.path('ENV_FILE', default='/'))
if os.path.isfile(ENV_FILE):
    overrides = {'DATABASE_URL': os.environ.pop('DATABASE_URL', '')}
    env.read_env(env_file=ENV_FILE, **overrides)
else:
    # unset if no file was found
    ENV_FILE = None

Problem is that in my ENV_FILE, I want to set DATABASE_URL that already has a value when reading the ENV_FILE.

But because def read_env(env_file=None, **overrides) uses setdefault(key, str(val)) this value can not be overwritten.

Is it possible to extend def read_env with an extra boolean argument to decide whether or not to override existing environment variables?

@ericpascual
Copy link

Got the exact same problem, and it turned me crazy to find why my code was not working.

By the way, the handling of the overrides argument is a bit strange, because the passed values will not override anything at the end of the day if the variable exists already. Maybe the setdefault used there is not intentional and it should have been a set instead.

@fdemmer
Copy link
Contributor

fdemmer commented Jun 29, 2017

@bmoelans do i understand correctly, that you have an environment variable DATABASE_URL that should take precedent over the same variable set in a file?

if so, you can just read the file without any overriding. read_env() does not overwrite existing environment variables.

the **overrides argument is confusing though... i'm going to create a pr to change that... not sure what the use case or intention was though, as the tests confirm the rather useless behaviour of not overriding anything.

@bmoelans
Copy link
Author

Well the reason of the issue is that we use docker containers for development and that certain variables are already set in docker-compose.yml file before launching Django. The reason behind this is that any developer can run the software out of the box.
I could use docker-compose.override.yml or so, but the env-file are more flexible to switch context.

What is the reason behind the fact that you do not allow to override already set settings?

What I did to solve it for now:

overrides = {'DATABASE_URL': os.environ.pop('DATABASE_URL', ''),
                   'DJANGO_SITE_TYPE': os.environ.pop('DJANGO_SITE_TYPE', '')}
env.read_env(env_file=ENV_FILE, **overrides)

@fdemmer
Copy link
Contributor

fdemmer commented Jun 30, 2017

What is the reason behind the fact that you do not allow to override already set settings?

i have no idea; not my code; just came to use this recently myself :)

my pull request would make your code sample work and override DATABASE_URL and DJANGO_SITE_TYPE.

@kerthcet
Copy link

so is there any result?

@kutenai
Copy link

kutenai commented Jul 9, 2018

The PR adds a new argument -- overwrite=False to read_env. When set to True, then values from the file overwrite any existing values.

I can only see one downside -- if "overrides" had a value named 'overwrite', then it would enable overwrite behavior.

It is unfortunate the the module uses **overrides as it does, since this puts a limit on adding any new keyword arguments.

I would personally like to see read_env deprecated as written, and replaced with a more flexible version, i.e.

def read_env(cls, env_file=None, overwrite=False, overrides=None):
    if overrides is not None:
        # do some overrides here.

@T-101
Copy link

T-101 commented Nov 21, 2018

Any chance of merging this PR?

@patrickjrm
Copy link

+1 for merging PR #191.

The similar python-dotenv project does have an override=True option.

https://github.com/theskumar/python-dotenv#getting-started

@sdementen
Copy link

any news on when this PR could be merged ?
I was bitten by a variant of this bug: an .env file containing twice the same variable for which I expected the last definition of the variable to be the final one

@JakeUrban
Copy link

I would also like this PR to be merged. I set fake ENV variables in my Dockerfile that I need to override with variables from my .env file.

@dantheman39
Copy link

Also would love for this to be merged.

@mpochron
Copy link

mpochron commented Mar 4, 2021

Simple to load env file to override environments from settings:

overrides = {key: os.environ.pop(key, value) for key, value in os.environ.items()}
environ.Env.read_env(env_file=str(ROOT_DIR.path('.env')), **overrides)

@sergeyklay
Copy link
Collaborator

This is resolved in develop branch. Thank you for the report, and for helping us make django-environ better. And I am sorry about the delay.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests