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

使用SQLAlchemy向SQL Server写入数据时编码错误求助

问题

我尝试用SQLAlchemy把数据写入SQL Server,代码如下:

def engine_():
   db_user = ''
   db_password = ''
   db_host = ''
   db_name = ''
   connection_format = 'mssql+pymssql://{0}:{1}@{2}/{3}?charset=utf8'
   connection_str = connection_format.format(db_user, db_password, db_host, db_name)
   engine = sqlalchemy.create_engine(connection_str)
   return engine

engine = engine_()
df.to_sql('111', con=engine, index=False, if_exists='replace')

执行后报错,改成charset=GBK还是报错。排查后发现是title列的编码问题,试过用str.normalize('NFKD')处理但没用。请问怎么解决?为什么用charset=utf8会触发20002错误?

部分title数据示例:

title
Artificial Plant Simulation Flower Lotus Water Lily Cumpleaños Para Niña
10cm artificial floating water lily EVA lotus pond ornaments artificial lotus pond aquarium plant ornaments
Gauge White Floral Stem Wire Iron Wire Artificial Flower Arrangement Wrapping Strip For Wedding Party DIY Flower Craft
解决方案

一、charset=utf8触发20002错误的原因

20002是pymssql的连接错误码,核心问题是SQL Server与pymssql的UTF-8支持不兼容:

  • SQL Server默认采用UTF-16(对应nvarchar/ntext类型)或GBK(对应varchar/text类型)编码,而pymssql的charset=utf8参数会强制以UTF-8编码传输数据,两者编码规则不匹配,直接导致连接或数据写入时的编码转换失败。
  • 另外pymssql本身对UTF-8的支持存在bug,遇到示例里的ñ这类特殊字符时,极易出现编码冲突触发报错。

二、具体解决方法

1. 换用pyodbc驱动替代pymssql

这是最稳定的方案,pyodbc对SQL Server的字符集支持更完善,无需手动指定charset:

def engine_():
    db_user = ''
    db_password = ''
    db_host = ''
    db_name = ''
    # 使用pyodbc连接格式,需提前安装ODBC Driver 17 for SQL Server
    connection_str = f'mssql+pyodbc://{db_user}:{db_password}@{db_host}/{db_name}?driver=ODBC+Driver+17+for+SQL+Server'
    engine = sqlalchemy.create_engine(connection_str)
    return engine

engine = engine_()
df.to_sql('111', con=engine, index=False, if_exists='replace')

注意:先执行pip install pyodbc安装依赖,同时确保系统已安装微软官方的ODBC Driver 17 for SQL Server。

2. 强制数据库列使用Unicode类型(保留pymssql的情况)

如果必须用pymssql,要确保SQL Server表中title列是nvarchar(Unicode类型),而非varchar,可以在to_sql中指定数据类型:

from sqlalchemy import NVARCHAR

df.to_sql(
    '111', 
    con=engine, 
    index=False, 
    if_exists='replace',
    dtype={'title': NVARCHAR(length=255)}  # 强制title列使用NVARCHAR类型
)

同时把连接字符串的charset参数改为utf8mb4或直接删除,让pymssql自动适配SQL Server的Unicode编码。

3. 预处理文本清理无效字符

如果仍有特殊字符报错,可手动过滤无法编码的无效字符:

def clean_title(text):
    # 过滤掉无法用UTF-8编码的字符
    return text.encode('utf-8', errors='ignore').decode('utf-8')

df['title'] = df['title'].apply(clean_title)

这个方法能剔除SQL Server无法识别的特殊编码字符,避免写入时触发错误。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.02 13:42:54