【问题标题】:Where does Flask look to find config files when using flask.config.from_object()?使用 flask.config.from_object() 时,Flask 在哪里寻找配置文件?
【发布时间】:2021-01-08 00:09:50
【问题描述】:

我这几天一直在尝试解决这个问题。我正在使用tutorial 中描述的应用程序设置运行烧瓶。下面是安装在虚拟环境中的包。

pip3 freeze

click==7.1.2 Flask==1.1.2 itsdangerous==1.1.0 Jinja2==2.11.2 MarkupSafe==1.1.1 pkg-resources==0.0.0 python-dotenv==0.15.0 Werkzeug==1.0.1

我在 .env 文件中有以下内容:

FLASK_APP=myapp

这样我就可以做到flask run。我的目录结构如下:

这都包含在一个名为“proj”的目录中

初始化.py

import os

from flask import Flask


def create_app(test_config=None):
    # create and configure the app
    app = Flask(__name__, instance_relative_config=True)
    app.config.from_object('conf.DevConfig')
    app.config.from_mapping(DATABASE=os.path.join(app.instance_path, 'tester.sqlite'))

    # ensure the instance folder exists
    try:
        os.makedirs(app.instance_path)
    except OSError:
        pass

    # a simple page that says hello
    @app.route('/hello')
    def hello():
        return 'Hello, World!'

    return app

在 proj 中,我运行 flask run 并获得以下信息:

werkzeug.utils.ImportStringError: import_string() failed for 'conf.DevConfig'. Possible reasons are:

- missing __init__.py in a package;
- package or module path not included in sys.path;
- duplicated package or module name taking precedence in sys.path;
- missing module, class, function or variable;

Debugged import:

- 'conf' not found.

Original exception:

ModuleNotFoundError: No module named 'conf'

注意在proj/instance/中有一个conf.py

conf.py 包含

class Config(object):
   DATABASE = 'tester.sqlite'

class DevConfig(Config):
   DEBUG = True

class ProdConfig(Config):
   DEBUG = False

奇怪的是,如果我将 conf.py 放在 proj/ 中,那么应用程序就可以正常加载了。我可以发誓我读到 Flask 会默认搜索 proj/instance 文件。为什么当我将它从实例移回一级时它会找到它。就此而言,可以将 .env 文件存储在实例中,并且烧瓶会自动找到它们吗?对我来说,instance_relative_config=True 似乎没有做它应该做的事情。调用flask run如果运行在proj/ vs proj/myapp有什么效果

【问题讨论】:

    标签: python flask config application-structure


    【解决方案1】:

    您可以将其视为(不是 100% 确定),当您执行 flask run 时,会调用并运行 create_app 函数。

    就像在app之外的proj中添加一个run_app.py文件,导入create_app函数作为运行它

    所以run_app.py

     from app import create_app
     app = create_app()
     if __name__=='__main__':
          app.run()
    

    这将运行服务器(就像你现在所做的那样) export FLASK_ENV=appexport FLASK_ENV=run_app.py 相同

    现在您已经在 conf.py 中添加了配置文件,并且当该文件位于 proj 文件夹中而不是 instance 文件夹中时,它对您来说工作正常。发生这种情况是因为在 app/__init__.py 文件中您已将配置对象的位置定义为 conf.DevConfig ,因此 python 也在 proj 文件夹中寻找此对象。

    因为你已经在instance/conf.py 文件中定义了配置对象,所以python 无法找到它并给你这个错误。

    要解决这个问题,您需要在app.config.from_object('conf.DevConfig')中提供对象的位置

    所以你可以通过两种方式做到这一点,

    第一。提供来自 proj 文件夹的完整 conf 对象路径,例如

     app.config.from_object('instance.conf.DevConfig')
    

    第二。导入app/__init__.py文件中的实例,然后提供配置对象

    例如。 app/__init__.py

    """      
    
    import other packages
    
    """
    from instance import conf
    
    
    def create_app(test_config=None):
        """
        app config thing here
        """
        app.config.from_object(conf.DevConfig)
        """
        config app more
        """
        return app
    

    注意,在方法一中,我将对象作为字符串提供,在方法二中作为类方法提供

    【讨论】:

    • instance_relative_config=True 不告诉flask 在实例文件夹中检查conf.DevConfig 吗?添加 instance.conf.DevConfig 确实有效,它似乎应该在实例文件夹中查找 conf.DevConfig。这可能只是我对包路径缺乏了解
    • 抱歉不知道,需要阅读文档
    • 也许这很简单,因为 conf.DevConfig 不是文件名。在 API 中重读后: instance_relative_config - 如果设置为 True 加载配置的相对文件名被假定为相对于实例路径而不是应用程序根目录。它是相对于实例路径的文件名。也许它以不同的方式对待包模块名称。我将尝试只制作一个 DevConfig.py 并查看它是否会仅使用 app.config.from_pyfile() 从实例加载
    【解决方案2】:

    app.config.from_object() 将搜索 flask run 的执行位置。在这种情况下,来自 /proj 目录

    app.config.from_pyfile() 将至少在 instance_relative_config 设置为 true 时进行搜索

    sahasrara62 提到:devConfig 类可以在 conf.py 中使用 'instance.conf.DevConfig' 找到

    我没有注意到任何证据表明flask run 添加了一个 run_app.py 文件并执行它,但似乎flask run 从它运行的目录开始

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-12-01
      • 2010-09-25
      • 2015-03-28
      • 2016-09-19
      相关资源
      最近更新 更多