Pandas含中文字符DataFrame写入数据仓库乱码问题求助
解决Pandas+pyodbc写入数据仓库中文乱码问题
老哥,你遇到的中文乱码问题主要出在两个地方:动态拼接SQL时的编码处理漏洞,还有pyodbc的编码配置没到位。另外直接拼SQL不仅容易乱码,还会有SQL注入风险,咱们直接一步到位解决,看下面的方案:
第一步:确认数据仓库表结构
首先得确保你要写入的表,对应的列是支持Unicode的类型:
- SQL Server:用
NVARCHAR/NTEXT(别用VARCHAR/TEXT,单字节存不下中文) - MySQL:把列设为
utf8mb4编码的VARCHAR/TEXT - PostgreSQL:直接用
TEXT或VARCHAR(默认支持UTF-8)
如果表结构不对,再怎么调代码都白搭!
第二步:调整pyodbc的编码配置
你原来的setencoding只设了SQL_CHAR,这是单字节字符类型,中文是多字节的,得换成SQL_WCHAR(对应Unicode),还要加上解码设置:
cnxn = database_connect() # 同时设置编码和解码,确保双向UTF-8支持 cnxn.setencoding(encoding='utf-8', ctype=pyodbc.SQL_WCHAR) cnxn.setdecoding(pyodbc.SQL_WCHAR, encoding='utf-8') cnxn.autocommit = True cursor = cnxn.cursor()
第三步:用参数化查询代替动态拼接SQL
这是解决乱码最关键的一步!动态拼字符串时,编码很容易在拼接过程中丢失,而参数化查询会让pyodbc自动处理编码转换,还能防SQL注入。修改后的代码如下:
# 读取CSV的代码保持不变 df = pd.read_csv(filename, dtype='str', encoding='UTF-8') # 构造参数化INSERT模板:用?作为占位符(pyodbc标准写法) columns_str = ', '.join(clm) placeholders = ', '.join(['?'] * len(clm)) insert_sql = f"INSERT INTO {tablename} ({columns_str}) VALUES ({placeholders})" # 遍历DataFrame每一行写入 for row_idx, row in df.iterrows(): # 处理NaN为空字符串,同时清理单引号(避免参数里的单引号干扰) row_values = [] for val in row: if pd.isna(val): row_values.append('') else: cleaned_val = str(val).strip().replace("'", "") row_values.append(cleaned_val) try: # 把参数列表传给execute,pyodbc自动处理编码 cursor.execute(insert_sql, row_values) print(f"第 {row_idx+1} 行写入成功") except Exception as e: print(f"写入第 {row_idx+1} 行出错:{str(e)}") print(f"出错的行数据:{row_values}")
为什么这样能解决问题?
- 参数化查询:pyodbc会把参数作为Unicode字符串传递给数据库,完全绕开了手动拼接时的编码丢失问题。
- SQL_WCHAR配置:明确告诉pyodbc用Unicode类型处理字符串,完美适配中文等多字节字符。
- 安全可靠:避免了SQL注入风险,比动态拼接SQL规范得多。
按这个方案改完,中文应该就能正常显示了!
内容的提问来源于stack exchange,提问作者KARTHI KEYAN
相关产品推荐
相关产品推荐

