SQLAlchemy的yield_per未按预期批量获取SQL Server数据问题
问题解决:SQLAlchemy连接SQL Server时yield_per未按预期分批取数
问题原因
SQLAlchemy的yield_per参数在连接SQL Server(使用pyodbc驱动)时默认不生效,因为pyodbc驱动会一次性将所有查询结果加载到客户端内存,直接忽略分批配置。必须配合stream_results=True开启流式结果传输,才能让yield_per按指定批次获取数据。
解决方案
修改代码,在execution_options中同时设置stream_results=True和yield_per=50_000,具体实现如下:
方式一:用partitions()遍历批次
with engine.connect() as conn: with open(csv_path, mode='w', newline='') as f: c = csv.writer(f, quoting=csv.QUOTE_MINIMAL) c.writerow(columns) # 同时开启流式传输与分批配置 result = conn.execution_options(stream_results=True, yield_per=50_000).execute(sql_string) for partition in result.partitions(): # 每个partition最多包含50000行数据 for row in tqdm.tqdm(partition): c.writerow(row)
方式二:直接遍历结果(自动分批)
with engine.connect() as conn: with open(csv_path, mode='w', newline='') as f: c = csv.writer(f, quoting=csv.QUOTE_MINIMAL) c.writerow(columns) # 同时开启流式传输与分批配置 result = conn.execution_options(stream_results=True, yield_per=50_000).execute(sql_string) # 遍历过程会自动按50000行一批次拉取数据 for row in tqdm.tqdm(result): c.writerow(row)
额外说明
- 驱动要求:确保使用
ODBC Driver 17 for SQL Server或更高版本,老旧驱动可能不支持流式传输特性。 - 数据库压力:110k行逐行获取不会造成类似DDOS的影响,但频繁小请求会增加交互开销;配置正确分批后,请求次数会降低至3次左右,减少不必要的资源消耗。
- 内存优化:开启流式传输后,客户端不会一次性加载所有数据,内存占用会显著降低,更适合处理大结果集场景。
内容的提问来源于stack exchange,提问作者scrollout
相关产品推荐
相关产品推荐

