如何覆盖 Flask 配置中的配置参数?

s5s*_*s5s 1 python flask flask-sqlalchemy

我正在使用烧瓶配置,我像这样配置我的应用程序:

app = Flask(__name__)
app.config.from_object('yourapplication.Config')
Run Code Online (Sandbox Code Playgroud)

我的配置对象是这样的:

class Config(object):
    DEBUG = True
    TESTING = False
    DB_USER = os.getenv("DB_USER", "db_user")
    DB_PASSWORD = os.getenv("DB_PASSWORD", "db_password")
    DB_HOST = os.getenv("DB_HOST", "localhost")  # 127.0.0.1"
    DB_PORT = os.getenv("DB_PORT", "5555")
    DB_SCHEMA = "my_schema"
    DB_DATABASE_NAME = "my_database"
    SQLALCHEMY_DATABASE_URI = "postgresql://{}:{}@{}:{}/{}".format(
        DB_USER, DB_PASSWORD, DB_HOST, DB_PORT, DB_DATABASE_NAME)
    SQLALCHEMY_TRACK_MODIFICATIONS = False
Run Code Online (Sandbox Code Playgroud)

我像这样运行我的应用程序(使用烧瓶脚本):

my_flask_app cmd1 arg1 arg2
Run Code Online (Sandbox Code Playgroud)

我想做以下事情:

DEBUG=true DB_PORT=1234 my_flask_app cmd1 arg1 arg2
Run Code Online (Sandbox Code Playgroud)

并覆盖 2 个配置参数。我想知道是否已经有一种方法可以从命令行覆盖配置参数,或者我是否应该编写一些代码?

编辑:为了澄清,我有几个从“Config(object)”继承的预设配置,如下所示:

class Dev(Config):
    pass

class Ua(Config):
    pass

class Prod(Config):
    DEBUG = False
Run Code Online (Sandbox Code Playgroud)

我的应用程序默认为“开发”配置。很容易想象一个场景,您想要运行“UA”配置但像这样覆盖端口:

FLASK_ENV=UA DB_PORT=1234 my_flask_app cmd1 arg1 arg2
Run Code Online (Sandbox Code Playgroud)

'FLASK_ENV' 将在内部选择 'UA' 配置对象,但我希望 DB_PORT 应用于顶部。只是想知道是否有扩展或有人对此有任何想法。

Dan*_*har 7

有几种方法可以覆盖。

1)使用config.from_envvar+ config.cfg。例子:

# test.py
import json

from flask import Flask, current_app


class Config(object):
    DEBUG = True
    TESTING = False
    DB_PORT = 1234


app = Flask(__name__)
app.config.from_object('test.Config')
app.config.from_envvar('YOURAPPLICATION_SETTINGS', silent=True)


@app.route('/')
def index():
    return json.dumps({
        'DEBUG': current_app.config['DEBUG'],
        'DB_PORT': current_app.config['DB_PORT'],
    })


if __name__ == '__main__':
    app.run()
Run Code Online (Sandbox Code Playgroud)

config.cfg

DB_PORT = 4321
DEBUG = False
Run Code Online (Sandbox Code Playgroud)

运行我们的应用程序:python test.py并打开http://127.0.0.1:5000/. 您将看到配置的默认值:

{"DEBUG": true, "DB_PORT": 1234}
Run Code Online (Sandbox Code Playgroud)

现在将路径添加config.cfgYOURAPPLICATION_SETTINGS变量中并重新启动应用程序。

export YOURAPPLICATION_SETTINGS={full_path_to}/config.cfg
python test.py
# open http://127.0.0.1:5000/ 
# you will see {"DEBUG": false, "DB_PORT": 4321}
Run Code Online (Sandbox Code Playgroud)

2)类似于第一种方式,但没有.cfg. test.py

import json
import os

from flask import Flask, current_app


class Config(object):
    DEBUG = True
    TESTING = False
    DB_PORT = 1234


class ProductionConfig(Config):
    DEBUG = False
    DB_PORT = 4321


class TestingConfig(Config):
    TESTING = True


app = Flask(__name__)
app.config.from_object(os.environ.get('CONFIG_CLASS', 'test.Config'))
# route + run ...
Run Code Online (Sandbox Code Playgroud)

如何检查:

python test.py # open http://127.0.0.1:5000/ - default config
# ProductionConfig config
export CONFIG_CLASS=test.ProductionConfig
python test.py # open http://127.0.0.1:5000/ - production config
Run Code Online (Sandbox Code Playgroud)

3)在某些情况下,只有 env 变量就足够了。

但要小心,你可能会遇到类型问题

import json
import os

from flask import Flask, current_app


class Config(object):
    DEBUG = True
    TESTING = False
    DB_PORT = 1234


app = Flask(__name__)
app.config.from_object('test.Config')
app.config.update({
    'DB_PORT': os.environ.get('DB_PORT', Config.DB_PORT)
    # you should to set type of variable here
    # DB_PORT will be string
    # 'DB_PORT': int(os.environ.get('DB_PORT', Config.DB_PORT))
})
# route + run ...
Run Code Online (Sandbox Code Playgroud)

让我们检查:

export DB_PORT=4321
python test.py
Run Code Online (Sandbox Code Playgroud)

打开http://127.0.0.1:5000/你会看到DB_PORT改变了但不是整数。因此,对于某些设置和特定情况,这是一个很好的解决方案。我认为1和2方式更好。

希望这可以帮助。


s5s*_*s5s 0

目前似乎没有实现此功能的标准方法或添加此有用行为的库。