我正在寻找一种从数据库条目设置一些静态应用配置值(如werkzeug服务器端口)的方法。我的应用程序使用SQLAlchemy和蓝图,目前从对象(config.py)获取配置。
假设数据库的配置仍来自配置文件,我如何从数据库配置应用程序的其余部分?
答案 0 :(得分:3)
从表中读取键/值项,并从这些项中设置配置。请记住,value列只能有一种类型(我在这里使用了String)。解决此问题的一种方法是创建具有不同值类型的多态表,但这超出了本答案的范围。我已经通过明确命名应该是不同类型的键来解决它。
import os
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
app = Flask(__name__)
# assuming the database is an sqlite file "app.db" in the instance folder
app.config['SQLALCHEMY_DATABASE_URI'] = os.path.join(app.instance_path, 'app.db')
db = SQLAlchemy()
db.init_app(app)
class ConfigItem(db.Model):
"""Represents one config item.
All values are strings, so non-string values must be converted later.
:param key: config key
:param value: configured value
"""
__tablename__ = 'config_item'
key = db.Column(db.String, primary_key=True)
value = db.Column(db.String)
def __str__(self):
return '{}: {}'.format(self.key, self.value)
def __repr__(self):
return 'ConfigItem(key={!r}, value={!r})'.format(self.key, self.value)
# map a converter function to key names, so that values will be converted from strings to the correct type
# this is just the mapper for Flask config keys, the list will be much longer will extension config keys added
config_types = {
lambda value: value == 'True': ('DEBUG', 'PROPAGATE_EXCEPTIONS', 'PRESERVE_CONTEXT_ON_EXCEPTION', 'SESSION_COOKIE_HTTPONLY', 'SESSION_COOKIE_SECURE', 'USE_X_SENDFILE', 'TRAP_HTTP_EXCEPTIONS', 'TRAP_BAD_REQUEST_ERRORS', 'JSON_AS_ASCII', 'JSON_SORT_KEYS', 'JSONIFY_PRETTYPRINT_REGULAR'),
int: ('PERMANENT_SESSION_LIFETIME', 'MAX_CONTENT_LENGTH', 'SEND_FILE_MAX_AGE_DEFAULT')
}
# convert the type to key list mapping above to a key to type mapping
config_types = {key: type for type, keys in config_types.items() for key in keys}
# flask_sqlalchemy database connections only work in an app context
# we're not in a request handler, so have to create the context explicitly
with app.app_context():
for item in ConfigItem.query:
# set the config value for each key, converting it if it's not a string
if item.key in config_types:
app.config[item.key] = config_types[item.key](value)
else:
app.config[item.key.upper()] = item.value