You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过pyodbc从Snowflake ODBC获取带表头的表格格式数据

获取带表头的表格格式数据解决方案

方法1:转换为Pandas DataFrame(推荐)

pyodbc的游标没有fetch_pandas_all()方法,但可以通过cursor.description提取列名,结合fetchall()获取全量数据,手动构造带表头的DataFrame:

import pyodbc
import pandas as pd

con = pyodbc.connect('DSN=Snowflake Conn')
con.setencoding(encoding='utf-8')
con.setdecoding(pyodbc.SQL_CHAR, encoding='utf-8')
cs = con.cursor()

# 注意:后续建议改用参数化查询避免SQL注入,先保留原查询结构
query = "select mr.entity_code as FUNDCODE, mr.AS_OF_DATE, mr.vol_contr_pc_abs * 3.549 EWMA_Vol_Annualised from risksd.tbl_market_risk mr join risksd.tbl_control_funds cf on cf.fundcode = mr.entity_code where model_code = 'GBL' and record_type = 'Portfolio' and mr.as_of_date ='"+last_business_day_string+"' and cf.fundcode in "+str(fundslist)
cs.execute(query)

# 提取列名:cursor.description里每个元素的第一个值就是列名
column_names = [col[0] for col in cs.description]
# 获取所有数据行
all_data = cs.fetchall()
# 构造DataFrame
result_df = pd.DataFrame(all_data, columns=column_names)

# 查看结果
print(result_df)

方法2:打印带表头的纯文本表格

如果不需要DataFrame,只是要直观的表格打印效果,可以用tabulate库(先执行pip install tabulate安装):

import pyodbc
from tabulate import tabulate

con = pyodbc.connect('DSN=Snowflake Conn')
con.setencoding(encoding='utf-8')
con.setdecoding(pyodbc.SQL_CHAR, encoding='utf-8')
cs = con.cursor()

query = "select mr.entity_code as FUNDCODE, mr.AS_OF_DATE, mr.vol_contr_pc_abs * 3.549 EWMA_Vol_Annualised from risksd.tbl_market_risk mr join risksd.tbl_control_funds cf on cf.fundcode = mr.entity_code where model_code = 'GBL' and record_type = 'Portfolio' and mr.as_of_date ='"+last_business_day_string+"' and cf.fundcode in "+str(fundslist)
cs.execute(query)

column_names = [col[0] for col in cs.description]
all_data = cs.fetchall()

# 打印带表头的网格状表格
print(tabulate(all_data, headers=column_names, tablefmt="grid"))

关键优化:避免SQL注入

原代码直接拼接字符串到SQL查询,存在安全风险。改用参数化查询更稳妥:

# 假设fundslist是字符串列表,比如['FUND001', 'FUND002']
# 生成对应数量的占位符
placeholders = ','.join(['?'] * len(fundslist))
# 用占位符替换拼接的部分
query = """
select mr.entity_code as FUNDCODE, mr.AS_OF_DATE, mr.vol_contr_pc_abs * 3.549 EWMA_Vol_Annualised 
from risksd.tbl_market_risk mr 
join risksd.tbl_control_funds cf on cf.fundcode = mr.entity_code 
where model_code = 'GBL' 
and record_type = 'Portfolio' 
and mr.as_of_date = ? 
and cf.fundcode in ({})
""".format(placeholders)

# 执行时传入参数:日期 + 基金列表转成的元组
cs.execute(query, (last_business_day_string,) + tuple(fundslist))

内容的提问来源于stack exchange,提问作者Manthan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.14 06:50:15