Flask: Как управлять базами данных различных сред?

Я работаю над приложением, которое похоже на

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 

Я хочу иметь три среды Dev, Test и Production.
У меня есть следующие требования:
а.) Когда я запускаю сервер python runserver.py, я хотел бы указать, какую среду я хочу подключить - Dev, Test или Production.
b.) Для Dev и Production должна быть построена схема, и им нужно просто подключиться к машине
c.) Я также хотел бы, чтобы мой тест подключался к sqlite db, создавал схему и запускал тесты.

Как я могу добиться этого с помощью конфигурации, чтобы мне не приходилось жестко кодировать что-либо, связанное с базой данных.

Есть ли хорошие шаблоны, доступные в колбе?

В настоящее время мой runerver.py имеет жесткое кодирование для среды, которая мне не нравится,

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

Я ищу лучшие идеи, чем у меня есть


person daydreamer    schedule 24.03.2013    source источник
comment
flask предоставляет пару примеров для начала работы в своей документации flask.pocoo.org/docs /config/#разработка-производство   -  person dm03514    schedule 25.03.2013


Ответы (5)


Решение, которое я использую:

#__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", второй файл конфигурации не требуется, а настройки .py по умолчанию для разработки и со значениями по умолчанию для общих ключей конфигурации

Если какой-либо другой файл settings_file будет загружен в дополнение к первому, значения внутри него переопределяют значения в исходном. (в моем примере 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"

person Tigra    schedule 26.03.2013
comment
flask.pocoo.org/docs/config/#configuring-from-files является хорошим источником дополнительной информации об этом - person Eddie; 07.04.2013

Я думаю, это то, что вы ищете:

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

Но также ознакомьтесь с проектом flask-empty, это шаблон для приложений flask с конфигурациями, специфичными для среды.

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, чтобы вы поняли идею:

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 обрабатывает настройку среды на основе переданных аргументов командной строки, однако вы можете получить представление о том, как это работает (обратите внимание, что для этого требуется 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() 

Отсюда вы можете выбрать требуемый класс Config из переменной среды или другим методом по вашему выбору.

person Eddie    schedule 06.04.2013

Вы можете создать модуль «config», который содержит конфигурацию для каждой среды. После этого текущую рабочую среду можно указать, установив переменную оболочки.

Если вы инициализируете приложение flask в основном файле 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)

Установка переменной окружения перед запуском сервера разработки или даже тестов может вызвать затруднения, поэтому я автоматизирую эти действия с помощью make-файла.

Также взгляните на flask-script http://flask-script.readthedocs.org/en/latest/.

person Ifthikhan    schedule 24.03.2013
comment
Недурно за наличие фактической среды в env var, а не имени модуля. - person linkyndy; 30.06.2015

Во Flask есть так называемые папки экземпляров, что позволяет иметь различные возможные конфигурации. и загрузить их соответственно.

person Devi    schedule 05.05.2014

Вы можете иметь свойства в settings.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» как development/local/test/production.

export FLASK_ENV="local"
person Joby Wilson Mathews    schedule 10.06.2020