ps:最近比較愁一些開發初始的設計問題,比較菜鳥經驗不足,吸收一些前輩的經驗之sql
-----------------------------------------------shell
Flask很讚的特色之一就是可擴展性強,很是靈活,對於config來講也是如此。Flask官方文檔中已經說起了很是多的方法,以及一些有用的建議。我在Flask項目開發中的config實踐,則是基於文檔中提到的類繼承方案,並經過環境變量來切換不一樣的config配置。數據庫
比較好的config方案是怎樣的呢?我以爲有以下幾點:flask
從這些需求點出發,下面分享一下我在Flask項目中的實踐經驗。api
/project_root /config __init__.py default.py development.py development_sample.py production.py production_sample.py testing.py /project __init__.py ...
全部的配置文件都存放在config
包中,而Flask app則位於project
包。對config
包中不一樣文件的作簡單的說明:服務器
__init__.py
:在這裏定義加載配置的函數default.py
:默認配置development.py
(不簽入Git):用於開發的config,每一個開發人員的development config能夠自定義development_sample.py
:development.py
的模板,每當有新成員加入dev團隊時,只需將其另存爲development.py
,而後根據本身的狀況填充對應項便可production.py
(不簽入Git):用於生產服務器的config,最好是由專人來管理production.py,其餘dev須要在服務器增長config項,一概向此人申請production_sample.py
:production.py
的模板,填好後能夠scp到服務器端testing.py
:用於測試的配置,測試的config應該是環境無關的(好比通常會使用sqlite數據庫進行測試,這樣就無需配置帳號密碼了),因此須要簽入Git中採用了基於類繼承的config結構,保存默認配置的Config類做爲基類,其餘類繼承之,以下:app
# default.py class Config(object): ... # development.py class DevelopmentConfig(Config) ... # production.py class ProductionConfig(Config) ... # testing.py class TestingConfig(Config) ...
這樣作的好處首先在於,經過繼承達到了config複用的目的。第二個好處來自IDE,好比PyCharm能夠對類中屬性是否爲override進行提示,以下圖:ide
有圈圈+向上箭頭標誌的行就是override自父類,沒有的就是本身定義的啦,一目瞭然。函數
以前提到過,在config/__init__.py
中會定義用於加載config的函數,加載策略以下:測試
MODE
,根據MODE
的取值加載不一樣的configMODE
環境變量不存在(或不合法),則默認加載development config用代碼表達就是:
# coding: UTF-8 import os def load_config(): """加載配置類""" mode = os.environ.get('MODE') try: if mode == 'PRODUCTION': from .production import ProductionConfig return ProductionConfig elif mode == 'TESTING': from .testing import TestingConfig return TestingConfig else: from .development import DevelopmentConfig return DevelopmentConfig except ImportError, e: from .default import Config return Config
在定義好config結構以後,就能夠加載了。須要儘早加載config,以便flask的一些第三方插件可以讀取配置,好比Flask-SQLAlchemy:
from flask import Flask from config import load_config # 絕對導入 from .models import db def create_app(): """建立Flask app""" app = Flask(__name__) # Load config config = load_config() app.config.from_object(config) db.init_app(app) ...
from flask import current_app config = current_app.config SITE_DOMAIN = config.get('SITE_DOMAIN')
經過改變環境變量MODE
來切換config,在不一樣應用場景下有不一樣的方法:
能夠在代碼中直接改變環境變量:
import os os.environ['MODE'] = 'TESTING'
在使用Fabric部署時,能夠經過shell_env
設置環境變量
from fabric.api import shell_env with shell_env(MODE='PRODUCTION'): # do something
在使用Supervisor管理Gunicorn進程時,能夠經過environment
配置項來設置環境變量:
[program:project_name] command = /var/www/project/venv/bin/gunicorn -c deploy/gunicorn.conf wsgi:app directory = /var/www/project user = deploy autostart = true autorestart = true environment = MODE="PRODUCTION"
我的建議在生產服務器上默認啓用PRODUCTION
模式,能夠在/etc/profile
末尾添加一行:
export MODE=PRODUCTION