美文网首页
关于Flask通过.env加载环境变量的两个坑

关于Flask通过.env加载环境变量的两个坑

作者: 阏男秀 | 来源:发表于2019-03-08 18:12 被阅读0次

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

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

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

    解决方案

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

    # `.env`
    MAIL_PORT = 465
    MAIL_USE_SSL = false
    MAIL_USE_TLS = true
    
    # 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加载环境变量时没有进行覆盖

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

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

    $ pipenv shell
    $ vim .env
    ...
    $ flask run
    

    解决方案

    方案一:重进pipenv shell

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

    > pipenv shell
    > # 编辑 .env
    ...
    > exit
    > pipenv shell
    

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

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

    # 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…信息):

    > $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

    如果有其他疑问,欢迎到HelloFlask论坛提问。

    相关文章

      网友评论

          本文标题:关于Flask通过.env加载环境变量的两个坑

          本文链接:https://www.haomeiwen.com/subject/hqldpqtx.html