SQLAlchemy查询指定列后如何实现类对象式点访问?
解决SQLAlchemy指定列查询返回类对象支持点访问的问题
方法1:用with_only_columns返回原模型实例(推荐)
这是SQLAlchemy原生支持的方式,查询指定列后仍返回原People类的实例,仅加载你指定的字段,未指定的字段会呈现默认值(如None),完全支持点访问:
from sqlalchemy.orm import with_only_columns # 构造查询,指定需要加载的列 query = with_only_columns(People.name, People.weight, People.hobby).select_from(People) result = session.scalars(query) # 遍历结果,支持点访问属性 for person in result: print(person.name, person.weight, person.hobby)
方法2:自定义数据类映射查询结果
如果不想依赖原模型,或者需要更轻量的结构,可以用Python标准库的dataclasses定义一个临时类,把查询返回的元组转换成类实例:
from dataclasses import dataclass # 定义对应指定字段的数据类 @dataclass class PeoplePartial: name: str weight: str hobby: str # 执行查询并转换为自定义类实例 raw_result = session.query(People.name, People.weight, People.hobby).all() people_list = [PeoplePartial(*item) for item in raw_result] # 点访问属性 for p in people_list: print(p.name, p.weight, p.hobby)
方法3:SQLAlchemy 2.0+ 用MappedAsDataclass定义专用类
针对SQLAlchemy 2.0及以上版本,可以直接定义一个继承自MappedAsDataclass的类,映射需要的字段,查询时直接关联:
from sqlalchemy.orm import MappedAsDataclass, mapped_column from sqlalchemy import select # 定义仅包含指定字段的映射类 class PeoplePartial(MappedAsDataclass): name: Mapped[str] = mapped_column(char(50)) weight: Mapped[str] = mapped_column(char(30)) hobby: Mapped[str] = mapped_column(char(30)) # 构造查询并返回类实例 query = select(PeoplePartial).from_statement( select(People.name, People.weight, People.hobby).alias() ) result = session.scalars(query) for person in result: print(person.name, person.weight, person.hobby)
补充:为什么Bundle没解决问题
sqlalchemy.orm.Bundle返回的是BundleResult对象,需要通过result.attrs或者索引访问字段,并非直接的模型类实例,因此无法像原模型那样直接点访问属性。
内容的提问来源于stack exchange,提问作者Loire
相关产品推荐
相关产品推荐

