如何让SQLAlchemy ORM的hybrid_property在asdict返回结果中显示
问题原因
默认asdict()的序列化逻辑只会采集ORM Mapper注册的表字段、column_property这类映射属性,hybrid_property是基于Python描述符实现的计算属性,不在Mapper默认的列属性采集列表里,所以不会被自动输出。
解决方案
方案1:重写Base类的asdict方法(通用方案)
在所有模型的父类Base里重写asdict逻辑,自动收集所有定义的hybrid_property,一次修改所有模型都生效:
from sqlalchemy import inspect from sqlalchemy.ext.hybrid import hybrid_property class Base: def asdict(self): # 先采集所有原生列、column_property字段 result = {col.key: getattr(self, col.key) for col in inspect(self).mapper.column_attrs} # 遍历采集所有hybrid_property属性 for attr_name, descriptor in inspect(self).mapper.all_orm_descriptors.items(): if isinstance(descriptor, hybrid_property): result[attr_name] = getattr(self, attr_name) return result
如果是使用sqlalchemy-utils库自带的asdict工具,也可以在调用时传入hybrid_properties=True参数(新版本支持该参数),直接自动包含混合属性:
from sqlalchemy_utils import asdict result = asdict(invoice, hybrid_properties=True)
方案2:序列化时手动追加字段
如果不想修改公共Base方法,在拿到实例后手动给序列化结果补值即可:
invoice = sess.query(Invoice).first() data = invoice.asdict() data["grand_total"] = invoice.grand_total
额外修正提示
你当前定义的grand_total表达式写法有错误,func.sum是SQL聚合函数,三个字段直接相加不需要调用该函数,否则查询层面调用该属性时会生成错误SQL,正确写法如下:
@grand_total.expression def grand_total(cls): return cls.total_amount + cls.cgst_amount + cls.sgst_amount
内容的提问来源于stack exchange,提问作者Naveen
相关产品推荐
相关产品推荐

