如何让Peewee ORM从CTE查询返回经过自定义字段转换的结果?
问题原因
Peewee从CTE中选取列时默认不会关联原表的自定义字段实例,因此不会触发自定义字段的python_value转换逻辑,可通过以下两种方法解决:
方案1:定义CTE时绑定列类型(最推荐)
在定义CTE时调用bind_columns()方法,为需要转换的列绑定对应自定义字段实例即可,示例如下:
# 定义递归CTE cte = (YourModel .select(YourModel.id, YourModel.my_enum_field, YourModel.parent_id) .where(YourModel.parent_id.is_null()) .cte('recursive_cte', recursive=True, columns=['id', 'my_enum_field', 'parent_id']) # 按columns定义的顺序绑定字段类型,不需要绑定的位置传None .bind_columns(None, YourModel.my_enum_field, None) ) # 拼接递归查询部分 cte = cte.union_all( YourModel.select( YourModel.id, YourModel.my_enum_field, YourModel.parent_id ).join(cte, on=(YourModel.parent_id == cte.c.id)) ) # 后续查询直接使用即可,会自动触发自定义字段转换 query = (cte .select_from(cte.c.id, cte.c.my_enum_field) .order_by(cte.c.id))
方案2:查询时显式指定字段类型
如果不方便修改CTE定义,也可以在调用select_from时通过原表字段的coerce方法绑定列类型:
query = (cte .select_from( cte.c.name, cte.c.level, cte.c.path, # 告知Peewee该列使用YourModel.my_enum_field的转换规则 YourModel.my_enum_field.coerce(cte.c.my_enum_field).alias('my_enum_field') ) .order_by(cte.c.path))
你之前使用的convert()方法未生效是因为该方法用于指定SQL层面的转换函数,而非Python层面的结果转换规则,因此不适用于该场景。
内容的提问来源于stack exchange,提问作者Keith
相关产品推荐
相关产品推荐

