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

如何用Pandas遍历SQL Server表列表并导出CSV?排查执行报错

SQL Server表导出CSV的问题排查与修复

问题场景

尝试通过Python从SQL Server导出所有基表为CSV文件,原始代码如下:

import pyodbc
import pandas as pd

cnxn_string = conn_str = pyodbc.connect(
    'Driver=ODBC Driver 17 for SQL Server;'
    'Server=server;'
    'Database=database;'
    'Trusted_Connection=yes;'
    )

select_all_tables_query = pd.read_sql_query("""SELECT table_name
FROM information_schema.tables
WHERE table_type = 'BASE TABLE'""", cnxn_string)
df_all_tables=pd.DataFrame(select_all_tables_query)

tables = df_all_tables['table_name']
for table in tables:
    sql_query=pd.read_sql_query("SELECT * FROM {table}", cnxn_string)
df=pd.DataFrame(sql_query)
df.to_csv(r'C:\path\{table}', index=False)

执行后出现语法错误:

pandas.errors.DatabaseError: Execution failed on sql 'SELECT * FROM {table}': ('42000', '[42000] [Microsoft][ODBC Driver 17 for SQL Server]Syntax error, permission violation, or other nonspecific error (0) (SQLExecDirectW)')

改为f-string后无输出,且收到警告:

c:\path_to_python_file.py:19: UserWarning: pandas only supports SQLAlchemy connectable (engine/connection) or database string URI or sqlite3 DBAPI2 connection. Other DBAPI2 objects are not tested. Please consider using SQLAlchemy.
  sql_query=pd.read_sql_query(f"SELECT * FROM {table}", cnxn_string)

错误原因分析

  1. 字符串未正确格式化:原始代码中"SELECT * FROM {table}"是普通字符串,Python不会替换{table}变量,导致SQL语句直接包含{table},触发语法错误。改为f-string后虽解决了替换问题,但仍存在循环逻辑错误。
  2. 循环逻辑错误:数据转换和导出代码写在循环外部,只会处理最后一个表的查询结果;同时CSV路径中的{table}未做格式化,无法生成对应表名的文件。
  3. pandas连接兼容性警告:pandas官方更推荐使用SQLAlchemy连接而非原生pyodbc连接,虽然pyodbc仍可工作,但会触发兼容性警告。

修复后的完整代码

import pyodbc
import pandas as pd

# 建立数据库连接
conn = pyodbc.connect(
    'Driver=ODBC Driver 17 for SQL Server;'
    'Server=server;'  # 替换为实际服务器名
    'Database=database;'  # 替换为实际数据库名
    'Trusted_Connection=yes;'
)

# 获取所有基表名称
tables_df = pd.read_sql_query(
    """SELECT table_name FROM information_schema.tables WHERE table_type = 'BASE TABLE'""",
    conn
)
table_names = tables_df['table_name'].tolist()

# 循环导出每个表为CSV
output_dir = r'C:\path'  # 替换为实际输出目录
for table in table_names:
    # 用方括号包裹表名,避免表名是SQL关键字导致报错
    query = f"SELECT * FROM [{table}]"
    df = pd.read_sql_query(query, conn)
    # 生成带表名的CSV路径
    csv_path = f"{output_dir}\\{table}.csv"
    df.to_csv(csv_path, index=False, encoding='utf-8-sig')  # 用utf-8-sig避免中文乱码

# 关闭连接
conn.close()

关键修复点

  • 用f-string正确格式化SQL语句和CSV路径,确保{table}被实际表名替换。
  • 将数据导出代码放入循环内部,保证每个表都被处理并生成对应文件。
  • 用[{table}]包裹表名,避免表名是SQL关键字(如User、Order)时触发语法错误。
  • 添加编码参数encoding='utf-8-sig',避免导出的CSV文件中文乱码。
  • 明确关闭数据库连接,释放资源。

关于pandas连接警告的处理

如果想消除警告,可改用SQLAlchemy建立连接,示例代码如下:

from sqlalchemy import create_engine
import pandas as pd

# 构建SQLAlchemy连接字符串
conn_str = "mssql+pyodbc://server/database?driver=ODBC+Driver+17+for+SQL+Server&trusted_connection=yes"
engine = create_engine(conn_str)

# 后续查询和导出逻辑与上面一致,只需将conn替换为engine

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.01 10:17:22