Flask: How to manage different environment databases?

后端 未结 5 1975
青春惊慌失措
青春惊慌失措 2020-12-13 11:27

I am working on an app which looks similar to

facebook/
         __init__.py
         feed/
             __init__.py
             business.py
             vi         


        
相关标签:
5条回答
  • 2020-12-13 11:46

    I think this is what your looking for:

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

    But also checkout the flask-empty project, it's a boilerplate for flask applications with environment specific configurations.

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

    You specify your configurations in config.py like so:

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

    This inherits the Config class which can contain your defaults. From there, main.py has methods for creating a flask instance from the config.py file, manage.py determines which config is loaded.

    Here's a snippet from main.py so you get the idea:

    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
    

    And then manage.py handles setup of the environment based upon command line arguments passed, however you can get an idea of how it works (note this requires flask-script):

    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() 
    

    From here you could choose the required Config class from an environmental variable, or other method of your choosing.

    0 讨论(0)
  • 2020-12-13 11:47

    You can create a "config" module which contains the configuration for each environment. Thereafter the currently running environment can be specified by setting a shell variable.

    If you are initializing your flask application in the main init file, the configuration also could be set there. This is how I set my configuration:

    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)
    

    Setting up environment variable before running the development server or even the tests can be a hassle, therefore I automate these actions with a makefile.

    Also take a look at flask-script http://flask-script.readthedocs.org/en/latest/.

    0 讨论(0)
  • 2020-12-13 12:01

    Solution I use:

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

    On the same level from which application loads:

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

    So. If Environment Variable MYCOOLAPP_CONFIG does not exist -> only settings.py will load, which refers to default settings (development server as for me)
    This is the reason for "silent=True", second config file not required, while settings.py default for development and with default values for common config keys

    If any other settings_file will be loaded in addition to first one values inside it overrides values in original one. (in my example DEBUG and SERVER_NAME will be overrided, while SECRET_KEY stays same for all servers)

    The only thing you should discover for yourself depends on the way how you launch your application
    Before launching ENVVAR MYCOOLAPP_CONFIG should be set
    For example I run with supervisor daemon and on production server I just put this in supervisor config file:

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

    With this way you can easily manage all your configuration files, moreover, with this way you can exclude this files from git or any other version control utility

    default Linux way is this one in console before launching:
    export MYCOOLAPP_CONFIG="/home/tigra/mycoolapp/settings_production.py"

    0 讨论(0)
  • 2020-12-13 12:02

    You can have the properties in setting.json like :

    {
      "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"
      }
    }
    

    And in code :

    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())
    

    Make sure you have added environment 'FLASK_ENV' as development/local/test/production.

    export FLASK_ENV="local"
    
    0 讨论(0)
  • 2020-12-13 12:04

    Flask has something called Instance folders, which makes it possible to have different possible configurations and load them accordingly.

    0 讨论(0)
提交回复
热议问题