从数据库条目获取应用配置

时间:2014-11-24 17:03:39

标签: python sqlite flask flask-sqlalchemy

我正在寻找一种从数据库条目设置一些静态应用配置值(如werkzeug服务器端口)的方法。我的应用程序使用SQLAlchemy和蓝图,目前从对象(config.py)获取配置。

假设数据库的配置仍来自配置文件,我如何从数据库配置应用程序的其余部分?

1 个答案:

答案 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