【问题标题】:Flask: How to manage different environment databases?Flask:如何管理不同环境的数据库?
【发布时间】:2013-03-24 19:55:04
【问题描述】:

我正在开发一个看起来类似于

的应用
facebook/
         __init__.py
         feed/
             __init__.py
             business.py
             views.py
             models/
                    persistence.py
                    user.py
         chat/
             __init__.py
             models.py
             business.py
             views.py
         config/
                dev.py
                test.py
                prod.py 

我想要三个环境DevTestProduction
我有以下要求:
a.) 当我启动服务器 python runserver.py 时,我想提一下我要连接的环境 - DevTestProduction
b.) Dev & Production 应该已经构建了架构并且只需要连接到机器
c.) 我还想让我的测试连接到sqlite db,并创建架构,运行测试

如何以配置方式实现这一点,这样我就不必对与数据库相关的任何内容进行硬编码。

flask 有什么好的模式吗?

目前我的runerver.py 对我不喜欢的环境进行了硬编码,

app = Flask(__name__)
app.config['SECRET_KEY'] = dev.SECRET_KEY

我正在寻找比我更好的想法

【问题讨论】:

标签: python flask flask-sqlalchemy


【解决方案1】:

我使用的解决方案:

#__init__.py
app = Flask(__name__)
app.config.from_object('settings')
app.config.from_envvar('MYCOOLAPP_CONFIG',silent=True)

在加载应用程序的同一级别:

#settings.py
SERVER_NAME="dev.app.com"
DEBUG=True
SECRET_KEY='xxxxxxxxxx'


#settings_production.py
SERVER_NAME="app.com"
DEBUG=False

所以。 如果环境变量 MYCOOLAPP_CONFIG 不存在 -> 只有 settings.py 会加载,它指的是默认设置(对我来说是开发服务器)
这就是“silent=True”的原因,不需要第二个配置文件,而 settings.py 默认用于开发,并且具有常用配置键的默认值

如果除了第一个值之外还加载任何其他设置文件,它会覆盖原始值中的值。 (在我的示例中,DEBUG 和 SERVER_NAME 将被覆盖,而所有服务器的 SECRET_KEY 保持不变)

您应该自己发现的唯一事情取决于您启动应用程序的方式
在启动 ENVVAR MYCOOLAPP_CONFIG 之前应该设置
例如,我使用主管守护进程运行,而在生产服务器上,我只是将其放入主管配置文件中:

environment=MYCOOLAPP_CONFIG="/home/tigra/mycoolapp/settings_production.py"

通过这种方式,您可以轻松管理所有配置文件,此外,通过这种方式,您可以从 git 或任何其他版本控制实用程序中排除这些文件

默认 Linux 方式是启动前控制台中的这种方式:
export MYCOOLAPP_CONFIG="/home/tigra/mycoolapp/settings_production.py"

【讨论】:

【解决方案2】:

我想这就是你要找的东西:

http://flask.pocoo.org/docs/config/#configuring-from-files

还要检查烧瓶空项目,它是具有特定环境配置的烧瓶应用程序的样板。

https://github.com/italomaia/flask-empty

您可以像这样在 config.py 中指定配置:

class Dev(Config):
    DEBUG = True
    MAIL_DEBUG = True
    SQLALCHEMY_ECHO = True
    SQLALCHEMY_DATABASE_URI = "sqlite:////tmp/%s_dev.sqlite" % project_name

这继承了可以包含您的默认值的 Config 类。从那里,main.py 具有从 config.py 文件创建烧瓶实例的方法,manage.py 确定加载哪个配置。

这是 main.py 中的一个 sn-p,所以你明白了:

def app_factory(config, app_name=None, blueprints=None):
    app_name = app_name or __name__
    app = Flask(app_name)

    config = config_str_to_obj(config)
    configure_app(app, config)
    configure_blueprints(app, blueprints or config.BLUEPRINTS)
    configure_error_handlers(app)
    configure_database(app)
    configure_views(app)

    return app

然后 manage.py 根据传递的命令行参数处理环境设置,但是您可以了解它是如何工作的(注意这需要烧瓶脚本):

from flask.ext import script

import commands

if __name__ == "__main__":
    from main import app_factory
    import config

    manager = script.Manager(app_factory)
    manager.add_option("-c", "--config", dest="config", required=False, default=config.Dev)
    manager.add_command("test", commands.Test())
    manager.run() 

您可以从这里从环境变量或您选择的其他方法中选择所需的 Config 类。

【讨论】:

    【解决方案3】:

    您可以创建一个“配置”模块,其中包含每个环境的配置。此后,可以通过设置 shell 变量来指定当前运行的环境。

    如果您在主 init 文件中初始化您的烧瓶应用程序,也可以在那里设置配置。这就是我设置配置的方式:

    def setup_config(app):
        """Set the appropriate config based on the environment settings"""
        settings_map = {'development': DevelopmentSettings,
                        'staging': StagingSettings,
                        'testing': TestingSettings,
                        'production': ProductionSettings}
        env = environ['ENV'].lower()
        settings = settings_map[env]
        app.config.from_object(settings)
    

    在运行开发服务器甚至测试之前设置环境变量可能很麻烦,因此我使用 makefile 自动执行这些操作。

    还可以查看 flask-script http://flask-script.readthedocs.org/en/latest/

    【讨论】:

    • 为在 env var 中包含实际环境而不是模块名称而点赞。
    【解决方案4】:

    Flask 有一个叫做Instance folders 的东西,它可以有不同的可能配置并相应地加载它们。

    【讨论】:

      【解决方案5】:

      您可以在 setting.json 中拥有如下属性:

      {
        "production": {
          "DEBUG": false,
          "APPLICATION_ROOT": "/app-root",
          "DB_URI": "mongodb://20.0.0.2:27017/TEST_DB",
          "FTP_HOST": "20.0.0.10"
      
        },
        "development": {
          "DEBUG": true,
          "APPLICATION_ROOT": "/app-root",
          "DB_URI": "mongodb://localhost:27017/TEST_DB",
          "FTP_HOST": "20.0.0.11"
        },
        "test":{
          "DEBUG": false,
          "APPLICATION_ROOT": "/app-root",
          "DB_URI": "mongodb://localhost:27017/TEST_DB",
          "FTP_HOST": "20.0.0.11"
        },
        "local": {
          "DEBUG": true,
          "APPLICATION_ROOT": "/app-root",
          "DB_URI": "mongodb://localhost:27017/TEST_DB",
          "FTP_HOST": "20.0.0.11"
        },
        "staging": {
          "DEBUG": false,
          "APPLICATION_ROOT": "/app-root",
          "DB_URI": "mongodb://localhost:27017/TEST_DB",
          "FTP_HOST": "20.0.0.19"
        }
      }
      

      在代码中:

      def load_setting():
          with open('setting.json', 'r') as file:
              return json.load(file)[os.getenv('FLASK_ENV')]
      
      app = Flask('TEST-APP')
      app.config.update(load_setting())
      

      确保您已将环境“FLASK_ENV”添加为开发/本地/测试/生产环境。

      export FLASK_ENV="local"
      

      【讨论】:

        猜你喜欢
        • 2021-03-13
        • 2018-11-09
        • 1970-01-01
        • 2020-10-10
        • 2020-08-09
        • 2011-02-27
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多