如何在SQLAlchemy 2.0中将计算列作为模型对象属性访问
解决方案
要实现直接通过行对象的row.obsolete_bool访问计算列值,有几种可行方式,按需选择即可:
方法1:直接利用Row对象的属性访问
你的查询已经为计算列添加了label("obsolete_bool"),SQLAlchemy 2.0返回的Row对象支持直接通过label名称访问对应值,模型实例则作为Row的第一个元素存在。修改代码如下:
case_stmt = case( (models.Evergreen.intended_remediation_date < models.Evergreen.obsolete_date, True), else_=False ).label("obsolete_bool") # 执行查询 result = await db.execute( select(models.Evergreen, case_stmt).where(models.Evergreen.id == id) ) # 获取单行结果 row = result.one() # 直接访问计算列 print(row.obsolete_bool) # 获取Evergreen模型实例 evergreen = row[0] # 多行结果遍历 rows = result.all() for row in rows: print(row.obsolete_bool) evergreen = row[0]
方法2:合并模型字段与计算列,返回统一属性的行对象
如果希望行对象同时包含模型所有字段和计算列(无需单独提取模型实例),可以直接选择模型的所有字段加上计算列:
from sqlalchemy import inspect # 获取Evergreen模型的所有字段 model_columns = inspect(models.Evergreen).columns case_stmt = case( (models.Evergreen.intended_remediation_date < models.Evergreen.obsolete_date, True), else_=False ).label("obsolete_bool") # 查询所有模型字段+计算列 result = await db.execute( select(*model_columns, case_stmt).where(models.Evergreen.id == id) ) row = result.one() # 直接访问模型字段和计算列 print(row.id) print(row.obsolete_bool)
方法3:在模型中定义混合属性(Hybrid Property)
如果希望直接通过Evergreen模型实例访问该计算值,无需在查询中单独定义case语句,可以给模型添加hybrid_property:
from sqlalchemy.ext.hybrid import hybrid_property from sqlalchemy import case class Evergreen(Base): __tablename__ = "evergreen" id = Column(Integer, primary_key=True) intended_remediation_date = Column(Date) obsolete_date = Column(Date) @hybrid_property def obsolete_bool(self): # 实例层面的计算逻辑 return self.intended_remediation_date < self.obsolete_date @obsolete_bool.expression def obsolete_bool(cls): # 查询层面的SQL表达式 return case( (cls.intended_remediation_date < cls.obsolete_date, True), else_=False )
之后查询时直接选择模型即可:
result = await db.execute( select(models.Evergreen).where(models.Evergreen.id == id) ) evergreen = result.scalar_one() # 直接通过模型实例访问计算值 print(evergreen.obsolete_bool)
内容的提问来源于stack exchange,提问作者moth
相关产品推荐
相关产品推荐

