0%

Flask环境变量加载踩坑

其实本质都是python-dotenv加载环境变量出现的问题。

坑一:python-dotenv加载的Value都是字符串类型

第一个坑是python-dotenv加载的Value都是字符串类型python-dotenv版本0.10.1),因此导致整型、浮点型和布尔类型需要转换一下。

解决方案

目前解决办法只能是这样:

1
2
3
4
# `.env`
MAIL_PORT = 465
MAIL_USE_SSL = false
MAIL_USE_TLS = true
1
2
3
4
5
6
# settings.py
class BaseConfig(object):
...
MAIL_PORT = int(os.getenv('MAIL_PORT', default=587))
MAIL_USE_SSL = True if 'true' == os.getenv('MAIL_USE_SSL') else False
MAIL_USE_TLS = True if 'true' == os.getenv('MAIL_USE_TLS') else False

相关帖子:https://discuss.helloflask.com/t/topic/127/3?u=angelliang

坑二:pipenv影响了flask加载.env环境变量

第二个坑和pipenv有关,众所周知Flask项目可以通过.env加载环境变量,但是,pipenv也可以通过.env加载环境变量!问题就出现了,进入pipenv shell虚拟环境后,修改.env环境变量后再启动Flask app:flask run,Flask还是用了原来的环境变量!!!

究其原因,是pipenv shell加载了环境变量并进行了缓存,然后flask加载环境变量时没有进行覆盖

1
2
3
4
5
6
7
> pipenv shell
Loading .env environment variables…
Launching subshell in virtual environment…
...
> flask run # 正常预期
# 停止flask,修改 .env 环境变量,保存
> flask run # 没达到修改变量后的预期效果

尤其是部署Flask到服务器后,以下步骤肯定有问题的!!!

1
2
3
4
$ pipenv shell
$ vim .env
...
$ flask run

解决方案

方案一:重进pipenv shell

一种解决方案就是退出pipenv shell环境再进入:

1
2
3
4
5
> pipenv shell
> # 编辑 .env
...
> exit
> pipenv shell

方案二:新建并使用app.py启动

另一个解决方案是在主目录下新建一个app.py,拷贝下面代码,以后使用python app.py启动。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# coding=utf-8
"""
python app.py
"""

import os
from dotenv import load_dotenv
dotenv_path = os.path.join(os.path.abspath(os.path.dirname(__file__)), '.env')
if os.path.exists(dotenv_path):
load_dotenv(dotenv_path, override=True) # override=True: 覆写已存在的变量

from apps.web import create_app

app = create_app()

if __name__ == "__main__":
app.run()

这种代码有时也会给一些wsgi(比如gunicorn)提供。

方案三:设置PIPENV_DONT_LOAD_ENV=1

还有一个方案是设置PIPENV_DONT_LOAD_ENV=1,不让pipenv加载.env

PowerShell示例(注意没有了Loading .env environment variables…信息):

1
2
3
4
5
> $env:PIPENV_DONT_LOAD_ENV=1
> pipenv shell
Launching subshell in virtual environment…
Windows PowerShell
...

方案四:使用.flaskenv

pipenv shell不会从.flaskenv加载变量,所以如果有经常需要修改的环境变量也可以放在.flaskenv。但是我感觉一点也不优雅,因为我习惯把.flaskenv也提交到仓库,而留下.env在部署端客制化。


相同帖子:https://discuss.helloflask.com/t/topic/128

iBoy wechat
欢迎您扫一扫上面的微信公众号,订阅我的博客!