如何将tqdm与cx.Oracle查询集成以实现实时进度显示
用tqdm给cx.Oracle查询添加实时进度条
要实现实时进度展示,核心思路是分批获取查询结果(而非一次性用fetchall()加载全部数据),这样就能在每批数据返回时更新进度条。结合tqdm可以轻松实现可视化进度,具体实现方案如下:
实现步骤与代码示例
1. 先获取查询总记录数(可选但推荐)
要让进度条准确显示百分比进度,需要先知道查询会返回的总行数。基于原查询的过滤条件,先执行一次COUNT统计:
import tqdm import pandas as pd import datetime import cx_Oracle # 假设已完成数据库连接初始化 # conn = cx_Oracle.connect(用户名, 密码, 连接串) cursor = conn.cursor() # 原查询语句 q2 = """ SELECT col1, col2 FROM TABLE1 WHERE col3 = (to_date('2024-03-31 00:20:00', 'yyyy-mm-dd HH24:MI:SS')) AND col2 >= (to_date('2024-03-01 00:00:00', 'yyyy-mm-dd HH24:MI:SS')) """ start_time = datetime.datetime.today() print("Started at", start_time.strftime("%H:%M:%S")) # 获取总记录数 count_q = q2.replace("SELECT col1, col2", "SELECT COUNT(*)") cursor.execute(count_q) total_rows = cursor.fetchone()[0] print(f"Total rows to fetch: {total_rows}")
2. 分批获取数据并绑定tqdm进度条
设置游标arraysize控制每批获取的行数(建议根据数据大小调整为1000-10000),然后用tqdm包裹迭代过程:
# 配置分批参数 batch_size = 2000 # 每批获取2000行,可按需调整 cursor.arraysize = batch_size cursor.execute(q2) # 用tqdm迭代收集数据 data = [] with tqdm.tqdm(total=total_rows, desc="Fetching data") as pbar: while True: batch = cursor.fetchmany(batch_size) if not batch: break data.extend(batch) pbar.update(len(batch)) # 转换为DataFrame并设置列名 b = pd.DataFrame(data) b.columns = [i[0] for i in cursor.description] # 输出耗时统计 end_time = datetime.datetime.today() elapsed_time = end_time - start_time print("Ended in", elapsed_time) print("Fetched", len(b), "rows...") # 关闭资源 cursor.close() # conn.close()
可选优化:无总数的进度条
如果COUNT查询本身耗时过长,可以省略总记录数获取,使用tqdm的无总数模式,此时进度条会显示已获取行数和处理速度:
with tqdm.tqdm(desc="Fetching data") as pbar: while True: batch = cursor.fetchmany(batch_size) if not batch: break data.extend(batch) pbar.update(len(batch))
关键说明
- 避免用
fetchall():一次性加载全部数据不仅无法反馈进度,还可能在数据量极大时触发内存溢出,分批获取能同时解决这两个问题。 arraysize的作用:控制每次网络请求获取的行数,合理设置能减少网络交互次数,平衡进度更新频率与查询效率。
内容的提问来源于stack exchange,提问作者MOA
相关产品推荐
相关产品推荐

