Skip to content

Result

Result表示 SQLAlchemy 中处理查询结果的接口,Result 统一了 fetchall、scalar 等查询接口的返回形式, execute() 函数现在统一返回 Result 对象。

Note

Result 通常针对的是 SELECT 语句的结果

Result 类型

SQLAlchemy 提供了多种 Result 类型,其中核心的包括三个类:

  • ScalarResult: 用于查询单列结果的 Result
  • ChunkedIteratorResult: 用于批量获取的结果
  • Row: 表示行

Reseult 中方法

成员 说明
all()->list[Row] 返回所有行,调用后关闭结果集(再次调用返回空序列)
close() 关闭结果集
columns(columns) 指定返回行中包含的列
fetchall()->list[Row] 同 all
fetchmany(size:int)->list[Row] 获取 size 行并消耗他们,所有行被消耗完毕后关闭结果集
fetchone()->Row 获取一行,当所有行消耗完毕返回 None
first()->Row 返回第一行后关闭结果集,如果不存在行返回 None
key() 返回列标签,可以使用dict(zip(keys(),row))来实现行数据转为字典
freeze()->FrozenResult 返回调用时该 Result 对象的副本
partitions(size:int)->Iterator[list[Row]] 循环访问给定大小的行的子列表,size 指定每次返回的列表大小。最后一行可能少于该值但是不会为空列表
mappings()->MappingResult 返回 MappingResult

Row 中方法

成员 说明
_asdict()->dict 返回字典
_fields 返回键元组
_mapping 返回 RowMapping
_tuple() 返回元组

Row 表示单行,他与 Python 的具名元组具有大致的行为,如果想要更加通用的就调用 ._asdict() 返回字典即可。

Result 使用要点

Result 对象中的行对象是一次性的或者说是消耗品,他只允许被迭代一次。而有些方法例如 firsst() 会直接消耗掉所有的行而仅仅返回第一行。我们可以通过 freeze() 来实现 Result 副本来避免被消耗(主要用于并发安全)。

调用 .all()fetchmany() 等方法会将全部数据加载到内存中,因此仅仅适合小型数据集。如果对于大型的数据集建议通过stream_results 服务器游标配合 .partitions(size) 来实现分块获取:

Python
with engine.connect() as conn:
    conn = conn.execution_options(stream_results=True)
    # conn.execute() 返回 CursorResult
    # 调用 CursorResult.mappings() 返回 MappingResult
    # docs 的结果类似 list[dict[str,any]]
    for docs in conn.execute(stem).mappings().partitions(1000):
        parse(docs)
    # 也可以, 核心在于 stream_results = True 开启服务端游标
    for docs in conn.execute(stem).partitions(1000):
        parse([doc._asdict() for doc in docs])