仓库源文站点原文


tags: [SQL Server, Python, bugfix] title: "pymssql编码问题报错UnicodeDecodeError: 'gbk' codec can't decode byte..." slug: pymssql-unicode-error

last_modified_at: 2023-11-1

TLDR

一言以概之,就是拿pyodbc换掉pymssql

安装msodbc驱动

Windows

首先阅读此Wiki了解驱动与SQL Server的版本对应关系,然后在下载页面选择对应链接下载并安装驱动

Linux

自行参阅此Wiki及该项目Wiki中的相关文章进行驱动的安装与配置。

使用pyodbc替换pymssql

pip install pyodbc安装pyodbc,并将代码里的pymssql改为pyodbc

连接数据库

把代码里的connect如下更改:

pymssql.connect(
            server=Config.DATABASE_ADDRESS,
            user=Config.DATABASE_USERNAME,
            password=Config.DATABASE_PASSWORD,
            database=Config.DATABASE_DB,
            charset="CP936",  # mssb
            tds_version="7.0",
        )

改为:

{% raw %}pyodbc.connect(f'DRIVER={{ODBC Driver 18 for SQL Server}};SERVER={Config.DATABASE_ADDRESS};DATABASE={Config.DATABASE_DB};UID={Config.DATABASE_USERNAME};PWD={Config.DATABASE_PASSWORD};TrustServerCertificate=yes'){% endraw %}

(注意,此处的18要改为你安装的驱动的版本,否则会报错)

(对于Linux,你必须使用DSN配置连接信息而不能使用上面的方法,具体自行参见Wiki

执行SQL

把代码里的Cursor对象的execute方法中的%s, %d等占位符全部换为?,即:

db.execute(
    "insert into [aa] ([name],[value]) values (%s, %d)",
    (name, value),
)

改为:

db.execute(
    "insert into [aa] ([name],[value]) values (?, ?)",
    (name, value),
)

完事!

其他解决方案

更改charset参数

pymssql.connect中的参数改为gbk/gb2312/gb18030/CP936可能有奇效<del>,但这太玄学了</del>。