返回

Docker+FastAPI 连接 SQL Server 出现 Unicode 错误怎么办?

Linux

Docker+FastAPI+SQLAlchemy 连接 SQL Server 遭遇 Unicode 转换错误? 解决方案在这里!

在使用 Docker、FastAPI 和 SQLAlchemy 构建应用程序,并尝试连接到 SQL Server 数据库时,你可能会遇到令人头疼的“Unicode conversion failed”错误。别担心,这篇文章将为你详细解析这个问题的来龙去脉,并提供简单有效的解决方案,帮助你快速解决这个难题。

错误现象:当数据库字符集遇上 Unicode

当你满怀期待地运行应用程序,尝试通过 SQLAlchemy 执行数据库操作时,却突然遭遇以下错误信息:

sqlalchemy.exc.DBAPIError: (pyodbc.Error) ('HY000', '[HY000] [Microsoft][ODBC Driver 18 for SQL Server]Unicode conversion failed (22) (SQLGetData)')
(Background on this error at: https://sqlalche.me/e/20/dbapi)

这个错误就像一个警报器,提示你在 Python 代码与 SQL Server 数据库之间进行数据交互时,Unicode 字符编码转换出现了问题,就好比两者说着不同的语言,无法相互理解。

深入剖析:问题根源在哪里?

导致这个错误的罪魁祸首主要有两个:

  1. 数据库排序规则 : SQL Server 数据库就像一个井然有序的世界,每个字符都有自己的位置。如果你的数据库使用了不支持 Unicode 的排序规则,例如 Japanese_CI_AS,那么在处理 Unicode 字符时就会出现问题,就像把一个讲日语的人扔到一个只懂英语的环境中。
  2. ODBC 驱动配置 : ODBC 驱动就像一座桥梁,连接着 Python 代码和 SQL Server 数据库。默认情况下,这座桥梁可能没有正确配置为使用 Unicode 进行字符编码,导致数据在传输过程中出现乱码。

解决之道:让数据库和代码“说”同一种语言

为了解决 Unicode 转换错误,我们需要确保数据库连接和数据交互过程都使用 Unicode 编码,就像为数据库和代码配备了翻译器,让他们能够顺畅地沟通。以下两种方法可以帮你轻松解决这个难题:

方法一:修改数据库连接字符串,指明 Unicode 编码

我们可以直接在 SQLAlchemy 的数据库连接 URL 中添加 charset=utf8 参数,强制使用 UTF-8 编码进行连接,就像在连接之初就明确告诉数据库和代码要使用同一种语言。

修改后的 database.py 代码如下:

import sqlalchemy as sa
from sqlalchemy import create_engine
import pyodbc
pyodbc.pooling = False

SQLALCHEMY_DATABASE_URL = sa.engine.url.URL(
    "mssql+pyodbc",
    username="user",
    password="pass",
    host="hostname",
    port=1433,
    database="test",
    query={
        "driver": "ODBC Driver 18 for SQL Server",
        "TrustServerCertificate": "yes",
        "charset": "utf8"  # 添加 charset 参数,明确使用 UTF-8 编码
    },
)
print(SQLALCHEMY_DATABASE_URL)

engine = create_engine(
    SQLALCHEMY_DATABASE_URL,
    pool_recycle=1500
)

方法二:修改数据库排序规则,从根本上解决问题(谨慎使用)

如果你拥有数据库的修改权限,并且确定修改排序规则不会影响现有数据,可以将数据库的排序规则修改为支持 Unicode 的规则,例如 Latin1_General_CI_ASSQL_Latin1_General_CP1_CI_AS,就像将整个数据库世界都改造成支持 Unicode 的环境。

注意: 修改数据库排序规则可能会导致数据丢失或应用程序异常,就像对整个世界进行改造一样,风险极高。请务必谨慎操作!建议在修改之前进行数据备份,以防万一。

常见问题解答

为了帮助你更好地理解和应用上述解决方案,我们整理了一些常见问题及其解答:

  1. 问:为什么修改数据库连接字符串后,错误仍然存在?

    答: 可能是因为你的 ODBC 驱动版本过低,不支持 charset 参数。尝试升级 ODBC 驱动到最新版本,或者使用其他支持 Unicode 的数据库连接库,例如 pymssql。

  2. 问:如何确定我的数据库当前使用的排序规则?

    答: 你可以使用 SQL Server Management Studio 或 Azure Data Studio 等数据库管理工具连接到数据库,然后在数据库属性中查看排序规则设置。

  3. 问:修改数据库排序规则后,需要注意哪些问题?

    答: 修改排序规则可能会影响数据存储和查询效率,甚至导致数据丢失。建议在修改之前进行充分测试,并备份数据库,以防万一。

  4. 问:除了上述两种方法,还有其他解决方法吗?

    答: 可以尝试在 Python 代码中使用 encode()decode() 方法对字符串进行手动编码和解码,确保数据在传输过程中使用 Unicode 编码。

  5. 问:如何避免未来再次出现 Unicode 转换错误?

    答: 在设计数据库和开发应用程序时,应始终将 Unicode 编码作为默认选择,并确保所有组件都支持 Unicode。

希望这篇文章能帮助你彻底解决 SQLAlchemy 连接 SQL Server 时遇到的“Unicode conversion failed”错误,让你的应用程序能够顺畅地与数据库进行数据交互!