Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/328.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/regex/20.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 为什么Flask不从config类配置某些环境变量?需要帮助理解配置过程吗_Python_Flask_Config - Fatal编程技术网

Python 为什么Flask不从config类配置某些环境变量?需要帮助理解配置过程吗

Python 为什么Flask不从config类配置某些环境变量?需要帮助理解配置过程吗,python,flask,config,Python,Flask,Config,我的应用程序似乎完全能够基于.env文件、导入的配置类进行配置,并直接定义变量。但是,FLASK\u DEBUG无法根据我如何定义变量进行更改 我可能应该注意到,我正在windows上使用Visual Studio代码。有人告诉我,我需要使用Linux或windows以外的任何东西,我也打算这样做,但现在这不是一个选项,因此,如果有人能帮助我了解这个系统的功能以及如何导航,我将不胜感激 config.py: import os basedir = os.path.abspath(os.path.

我的应用程序似乎完全能够基于
.env
文件、导入的配置类进行配置,并直接定义变量。但是,
FLASK\u DEBUG
无法根据我如何定义变量进行更改

我可能应该注意到,我正在windows上使用Visual Studio代码。有人告诉我,我需要使用Linux或windows以外的任何东西,我也打算这样做,但现在这不是一个选项,因此,如果有人能帮助我了解这个系统的功能以及如何导航,我将不胜感激

config.py:

import os
basedir = os.path.abspath(os.path.dirname(__file__))

class DevelopmentConfig(object):
    os.environ['SECRET_KEY'] = b'something'
    os.environ['SQLALCHEMY_DATABASE_URI'] = os.environ.get('DATABASE_URL') or \
        'sqlite:///' + os.path.join(basedir, 'app.db')
    os.environ['SQLALCHEMY_TRACK_MODIFICATIONS'] = 'False'
    os.environ['FLASK_DEBUG'] = '1'
    os.environ['DEV_DICT'] = 'dev_config_class_environ_dictionary_activated_and_working'

class ProductionConfig(object):
    os.environ['SECRET_KEY'] = os.environ.get('SECRET_KEY')
    os.environ['SQLALCHEMY_DATABASE_URI'] = os.environ.get('PRODUCTION_DATABASE_URI')
    os.environ['SQLALCHEMY_TRACK_MODIFICATION'] = 'False'
    os.environ['FLASK_DEBUG'] = '0'
    os.environ['PROD_DICT'] = 'prod_config_class_environ_dictionary_activated_and_working'

init.py:

from flask import Flask
from config import DevelopmentConfig, ProductionConfig
from flask_migrate import Migrate
from flask_sqlalchemy import SQLAlchemy
from dotenv import load_dotenv, find_dotenv
import os

app = Flask(__name__)
db = SQLAlchemy(app)
migrate = Migrate(app, db)

load_dotenv(find_dotenv())

if os.environ.get('FLASK_ENV') == 'development':
    print("Environment is development")
    app.config.from_object(DevelopmentConfig)
elif os.environ.get('FLASK_ENV') == 'production':
    print("Environment is production")
    app.config.from_object(ProductionConfig)

print(os.environ.get('TEST_DOTENV'))   #This value is stored in .env
print(os.environ.get('DEV_DICT'))      #defined in class DevelopmentConfig as os.environ['DEV_DIVT']
print(os.environ.get('PROD_DICT'))     #same but in the ProductionConfig class
print(os.environ.get('FLASK_ENV'))     #defined differently in both classes and CONFIGS CORRECTLY
print(os.environ.get('FLASK_DEBUG'))   #defined differently in both classes and DOES NOT CONFIG CORRECTLY

.env:

当我运行应用程序时:

(flaskvenv) PS C:\Users\peter\Desktop\Projects\Social Work Site\sw_app> flask run
 * Serving Flask app "run.py" (lazy loading)
 * Environment: development
 * Debug mode: on
 * Restarting with stat
c:\...__init__.py:814: UserWarning: Neither SQLALCHEMY_DATABASE_URI nor SQLALCHEMY_BINDS is set. Defaulting SQLALCHEMY_DATABASE_URI to "sqlite:///:memory:".
  'Neither SQLALCHEMY_DATABASE_URI nor SQLALCHEMY_BINDS is set. '
c:\...__init__.py:835: FSADeprecationWarning: SQLALCHEMY_TRACK_MODIFICATIONS adds significant overhead... 

Environment is development                                     #changes correctly if I change it in .env
config_from_dotenv_is_working                                  #further proof .env works fine
dev_config_class_environ_dictionary_activated_and_working      #prints regardless of which class gets called
prod_config_class_environ_dictionary_activated_and_working     #also prints regardless of which class gets called
development                                                    #changes to production properly if I change it in .env
0                                       #stubbornly stays set to 0 regardless of it being set in config

 * Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)
奇怪的是:

当我在
.env
文件中定义
FLASK\u DEBUG
时,命令行会在自动输出中正确显示它,例如
*DEBUG mode:off
*DEBUG mode:on
,具体取决于我是否分别将其设置为
0
1

但是当我用
os.environ.get('FLASK\u DEBUG')
调用它时,不管我做什么,它都显示为0

基于此,我有几个问题

主要问题和问题的实质当然是:

  • 为什么Flask没有配置
    Flask\u DEBUG
    ,但其他变量配置良好
  • 我怀疑其他问题可能有某种联系,并有助于我理解这一点:

  • Windows操作系统在这个问题中扮演什么角色
  • 如果我只调用其中一个,为什么两个配置类都在配置环境变量
  • 为什么如果自动输出告诉我
    Debug mode
    on
    os.environ.get('FLASK\u Debug')
    仍然返回
    0
  • 我可以通过在
    .ENV
    中定义
    FLASK\u ENV
    来解决这个问题,但我想了解它是如何工作的。事物配置方式的差异让我感到不安,因为我不知道事物是如何或为什么以这样的方式运行的


    提前谢谢

    您混淆了配置类和环境变量的概念

    解释你的结果 如果您定义了两个类,并且在这些定义中立即设置了环境变量,那么这两个类都将立即运行。不要这样做:

    # config.py
    import os
    
    class DevelopmentConfig(object):
        os.environ['FLASK_DEBUG'] = '1'
    
    class ProductionConfig(object):
        os.environ['FLASK_DEBUG'] = '0'
    
    print('FLASK_DEBUG is', os.environ['FLASK_DEBUG'])
    
    运行此代码后,两个类都将设置env。变量,并且由于0是最后一个要设置的值,因此结果将为0:

    $ python config.py
    FLASK_DEBUG is 0
    
    这就是您的
    FLASK\u DEBUG
    始终为0的原因。无论在
    .env
    文件中设置了什么,都将运行
    DevelopmentConfig
    ProductionConfig
    中的所有代码。您的问题与Windows无关

    除了类之外,您还可以从
    .env
    文件中设置环境变量,包括
    FLASK\u env=development
    。这是一个由Flask识别的变量,它将打开调试模式。这是在Flask中启用调试模式的原因

    一种解决方案:使用特定于环境的配置类 在类中定义值:

    class DevelopmentConfig(object):
        MY_VARIABLE = 'dev value'
        ...
    
    class ProductionConfig(object):
        MY_VARIABLE = 'prod value'
        ...
    
    然后在环境变量中设置环境。这可以直接在操作系统中完成,如果愿意,也可以使用.env文件:

    FLASK_ENV=development
    
    在生产服务器上,您将创建一个不同的.env文件:

    FLASK_ENV=production
    
    然后在烧瓶中装入相关等级:

    from dotenv import load_dotenv, find_dotenv
    from flask import Flask
    import os
    
    load_dotenv(find_dotenv())    
    app = Flask(__name__)
    config = ProductionConfig() if os.environ.get('FLASK_ENV') == 'production' else DevelopmentConfig()
    app.config.from_object(config)
    print(app.config['MY_VARIABLE'])
    
    在这种情况下,您甚至不需要设置
    FLASK\u DEBUG
    ,因为FLASK将根据
    FLASK\u ENV
    自动设置它

    其他解决方案
    您还可以完全放弃配置类,而是从环境变量或配置文件导入所有值。有关更多详细信息,请阅读

    谢谢你,安德斯!这是有道理的。我开始在配置类中定义环境变量的原因(我现在意识到这是错误的)是,当我将它们定义为变量时,它们不起作用。配置类(
    DEV_DICT
    PROD_DICT
    )中的测试变量在我定义它们时打印
    None
    ,比如:
    SECRET\u KEY=b'something'
    。我会接受你的回答,因为它解决了眼前的问题,并提出了另一个问题,但是关于为什么会出现这种情况的其他建议,可以从上面看到吗?如果你定义一个类
    class DevelopmentConfig:
    和一个类变量
    SECRET\u KEY=b'something'
    ,调用
    DevelopmentConfig().SECRET_KEY
    不返回none。嗯,我一定是弄错了什么,因为它现在正在工作。好的,很好。再次感谢!
    from dotenv import load_dotenv, find_dotenv
    from flask import Flask
    import os
    
    load_dotenv(find_dotenv())    
    app = Flask(__name__)
    config = ProductionConfig() if os.environ.get('FLASK_ENV') == 'production' else DevelopmentConfig()
    app.config.from_object(config)
    print(app.config['MY_VARIABLE'])