Package: confio
配置读写组件此组件用于对本地配置进行读写，目前支持以下类型的配置：ConfFS文件系统ConfDB数据库 (默认使用 MySQL)ConfConsulTODOs配置值加密支持其它配置源支持Redissqliteiniyamlpropertiestoml概述此组件针对不同的数据源提供了相同的数据读写接口，以避免开发过程中，读写不同数据源中配置的差异，以及无缝切换数据源。配置文件配置文件的存储基于 JSON 格式，并且扁平化读写。 配置项在配置文件中，以数组的方式存在，每项为一个配置项。可使用的配置字段如下：name配置项名称id_配置项标识，建议均为小写value系统值user_value用户值desc描述enabled是否启用，默认为true(保留字)，暂未使用其中，value为系统设置的值（或者叫做默认值），user_value为用户设置的值，通过.value取值时，会优先获取user_value，为空时会使用value字段名称value可以添加一些类型修饰符，详见#类型修饰符一般来说，在项目的开发过程中，使用 json 数据格式来对配置进行管理。
而在线上运行时，使用数据库对配置进行管理。类型修饰符类型修饰符用于简化一些数据的写法。只能写在value字段名上，其作用于value和user_value的值，写法如下：{"value:path":"../to/path"}其中的:path就是修饰符，可选值好如下：不指定类型path其值为一个文件系统的路径在这种情况下，字段名称type值为path其值可以是绝对路径，或者相对路径（相对于项目根目录）。 当其为相对路径时，组件会自动计算出其绝对路径在这种情况下，需要通过ValueParser.PATH_ROOT=或者ValueParser(path_root=)expr其值为一个表达式在这种情况下，字段名称type值为expr一般来说，仅仅在字段的数据类型为数值时才应该指定这种类型其值应该是一个合法的 python 表达式（其中不能包含需要通过外部导入的模块）例：60 * 10,5 * (20 + 8 * (27 - 4))通过.value得到的值单位均为 数值类型intsize其值为文件大小在这个情况下，字段名称type值为size一般来说，仅仅在配置文件/占用空间大小等需要使用存储单位时才使用此值使用的进制为1024写法：允许使用k/m/g/t作为单位例：10m,50g通过.value得到的值单位均为 数值类型bytetime其值为时间范围（多少年，月，天，小时，分，秒）在这个情况下，字段名称type值为time一般来说，仅仅在时间范围相关等需要使用时间存储单位时才使用此值写法：允许使用以下作为单位区分大小写s秒（可以省略）m分钟h小时D天M月（一个月仅按30天计算）Y年（一年按365天计算）例：10m10 分钟500500 秒1h20m1 小时 20 分通过.value得到的值单位均为 数值类型秒当指定类型修饰符时，value和user_value的值必须是一个字符串快速上手配置文件/config/module1/conf.json[{"key":"foo","value":"bar","name":"test"},{"...":"..."}]fromconfioimportConfFSconf_root='/config'conf=ConfFS(conf_root)# 配置项存在，得到值 barconf.get('module1.conf.foo')# 配置项不存在，得到值 Noneconf.get('module1.conf.bar')# 配置项不存在，使用默认值 'foo'conf.get('module1.conf.bar',default='foo')# 匹配所有以 module1.conf 开头的项conf.match('module1.conf')初始化ConfFS基于文件系统 (JSON 格式) 的配置存储，其通过目录和文件进行模块分割。fromconfioimportConfFSconf=ConfFS(conf_root='/config')conf_root存放配置文件的根目录(应该是一个绝对路径)，所有的配置模块，基于此目录计算。此模块会自动缓存。在文件更改后会自动更新缓存(主动模式，即读取时才会更新)ConfDB基于数据库的配置存储。ConfDB依赖dbutils和PyMysql包。fromconfioimportConfDBconf=ConfDB(database='database-name',host='127.0.0.1',port=3306,user='root',password='',charset='',table_name='conf_items')在使用数据库时，其表名称默认为conf_items可以指定一个值处理器ValueParser，其用于处理字段type指定的不同类型。可以指定一个自定义的枚举类型，其用于扩展内置的ConfTypes枚举，在使用了自定义的type时会用到。在系统内使用了type=path时，那么需要通过以下方式指定根路径:fromconfioimportValueParser,ConfItem# 指定全局的根路径ValueParser.PATH_ROOT='xxx'# 按实例指定根路径parser=ValueParser('xxx')ConfItem.parser=parserfromenumimportEnumclassMyConfTypes(Enum):XXX='xxx'"""支持 type="xxx": "key:xxx": 123"""ValueParser.enum_class_ext=MyConfTypes值处理拦截器fromconfioimportValueParser,ConfTypesdefvalue_handler(parse_type:ConfTypes,raw_value,parsed_value,prev_value):returnprev_valueValueParser.add_interceptor(value_handler)接口说明在以下文档中，fs.abc()表示ConfFS().abc()db.abc()表示ConfDB().abc()load加载所有配置项load() -> List[ConfItem]参数：无返回：所有配置项的列表get获取指定配置项的值。get(id_: str, default=None, value_only=True) -> Union[ConfItem, Any]参数：id_指定的配置项 ID。其必须是与配置名称完全一致default指定的默认值。当指定的配置项不存在时，使用此值value_only是否仅返回配置项的值。指定为True时表示仅返回配置项的值， 为False时表示返回ConfItem对象返回：返回一个ConfItem对象(value_only=False)或具体的某个字段的值match获取匹配指定前缀的所有配置项的值。match(prefix: str, value_only=True, fullkey=False) -> Dict[str, Union[ConfItem, Any]]参数：prefix指定的前缀。其必须按模块指定，如： 存在模块aaa.bbb.ccc，只能通过aaa或aaa.bbb进行匹配， 不能通过aa或aaa.b或者aaa.bbb.ccc进行匹配value_only是否仅返回配置项的值。指定为True时表示仅返回配置项的值， 为False时表示返回ConfItem对象fullkey是否返回完整的id_返回：配置项的键值对集合。当fullkey=True时，键名称为键名全称，否则为除去prefix后的名称如：prefix='aaa'，有配置项aaa.bbb.ccc=5， 当fullkey=True时，返回{'aaa.bbb.ccc': 5}； 当fullkey=False时，返回{'bbb.ccc': 5}；set添加/更新配置项的值。set(id_: str, value, update_sys_value=False, allow_add=False):参数：id_指定的配置项value指定配置项的值，当此值类型为ConfItem时，会更新配置项的所有属性update_sys_value是否更新系统值，默认情况下更新用户值allow_add在指定项不存在时，是否允许添加新的配置项返回：无注意：当在更新用户值时， confio 会检查用户值与系统值的数据类型是否一致。batch_set批量添加/更新配置项的值。set(items: Union[Dict[str, Any], List[ConfItem]], prefix: str = None, update_sys_value=False, allow_add=False):参数：items指定的配置项prefix指定的配置项使用的前缀。在指定了此值后，会给items中的每一项的ID添加此前缀value指定配置项的值update_sys_value在value不为ConfItem类型时有效。是否新增为系统值，默认情况下新增为用户值allow_add在指定项不存在时，是否允许添加新的配置项返回：无remove移除指定的配置项。remove(id_: Union[str, List[str], Tuple[str]]) -> Optional[Union[ConfItem, List[ConfItem]]]注意：指定的项不存在时，此项操作会被忽略。参数：id_要移除的配置项 ID(或 ID集合)返回：无钩子为了便于对读写的值进行处理，可以实现钩子来对其进行自定义处理。fromrestfximportIHook,ConfItemclassMyHook(IHook):defread_value(self,item:ConfItem):returnTrue,'customize_value'defread_raw_value(self,item:ConfItem):returnTrue,'customize_value'ConfItem.hooker=MyHook()