提问: config.ini 文件里面如何配置 json 格式的数据?

276 天前
 codists

一、说明

Flask 项目使用的配置文件是 config.ini ,示例:

[flask]
FLASK_APP=run.py
FLASK_ENV=produce
FLASK_PORT=8000
SECRET_KEY=''

[local]
DEBUG=1
DATABASE_URL=mysql://root:root@127.0.0.1:3306/database_local
SQLALCHEMY_POOL_RECYCLE=3600

[test]
DEBUG=1
DATABASE_URL=mysql://root:root@127.0.0.1:3306/database_test
SQLALCHEMY_POOL_RECYCLE=3600

[produce]
DEBUG=0
DATABASE_URL=mysql://root:root@127.0.0.1:3306/database_produce
SQLALCHEMY_POOL_RECYCLE=600

二、问题描述

flask-sqlalchemy 3.1 版本 SQLALCHEMY_POOL_RECYCLE 配置被移除了,变成如下方式:

SQLALCHEMY_ENGINE_OPTIONS = {
    "pool_recycle": 600,
}

目前的解决方式是写在读取配置文件的类里面:

import configparser
import os

cf = configparser.ConfigParser()
config_dir = os.path.dirname(os.path.abspath(__file__))

cf.read(os.path.join(config_dir, "config.ini"))


class Config:

    # Flask
    FLASK_ENV = cf.get("flask", "FLASK_ENV")
    SECRET_KEY = cf.get("flask", "SECRET_KEY")
    FLASK_PORT = cf.getint("flask", "FLASK_PORT")
    DEBUG = True if cf.getint(FLASK_ENV, "DEBUG") else False

    # SQLALCHEMY
    SQLALCHEMY_DATABASE_URI = cf.get(FLASK_ENV, "DATABASE_URL")
    SQLALCHEMY_ENGINE_OPTIONS = {
        "pool_recycle": 600
    } # 这样就无法区分 local 、test 、produce 环境

但是,这样写会导致一个问题——local 、test 、produce 三个环境都使用了相同的 pool_recycle ,不满足需求。请问在 config.ini 里面如何根据不同的环境配置不同的 SQLALCHEMY_ENGINE_OPTIONS(或 pool_recycle)?

请各位大佬指点指点,谢谢。

2321 次点击
所在节点    Python
9 条回复
nulIptr
276 天前
如果是我的话可能会把配置文件整个都改成 json 或者 yaml
想改动小的话不改配置文件,读文件的时候做个映射不得了
比如
SQLALCHEMY_ENGINE_OPTIONS = {
"pool_recycle": cf.getint(FLASK_ENV, "SQLALCHEMY_POOL_RECYCLE")
}
linauror
276 天前
按 1 的配置写法,这样直接去取不行吗?把代码中的 600 直接替换为 cf.get(FLASK_ENV, "SQLALCHEMY_POOL_RECYCLE")
codists
276 天前
codists
276 天前
感谢两位大佬的解答。
lisongeee
276 天前
能不能将 ini 后缀改成 toml, 然后使用 tomlkit 模块读取

然后只需要把 SQLALCHEMY_ENGINE_OPTIONS={"pool_recycle": 600,} 正常放在 SQLALCHEMY_POOL_RECYCLE=3600 的下面一行就行
lisongeee
276 天前
好像还得把原来的字符串类型如 produce 和 mysql://root 加上引号才行
LeeYD
275 天前
config.py
```python
import os

class Config:
SECRET_KEY = os.environ.get('SECRET_KEY', '')
SQLALCHEMY_ENGINE_OPTIONS = {
"pool_recycle": 600
}

class LocalConfig(Config):
DEBUG = True
DATABASE_URL = 'mysql://root:root@127.0.0.1:3306/database_local'
SQLALCHEMY_POOL_RECYCLE = 3600

class TestConfig(Config):
DEBUG = True
DATABASE_URL = 'mysql://root:root@127.0.0.1:3306/database_test'
SQLALCHEMY_POOL_RECYCLE = 3600

class ProductionConfig(Config):
DEBUG = False
DATABASE_URL = 'mysql://root:root@127.0.0.1:3306/database_produce'
SQLALCHEMY_POOL_RECYCLE = 600
```

run.py
```python
from flask import Flask
from config import LocalConfig, TestConfig, ProductionConfig

app = Flask(__name__)

env = 'production'

if env == 'local':
app.config.from_object(LocalConfig)
elif env == 'test':
app.config.from_object(TestConfig)
elif env == 'production':
app.config.from_object(ProductionConfig)

```
codists
275 天前
@lisongeee 感谢大佬的解答,toml 确实支持 json(table)的配置。
codists
275 天前
@LeeYD 感谢大佬的解答,这里主要是讨论配置文件(如.env, .ini, yaml, json, toml 等文件)对 json 的支持。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/1016294

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX