Django pyodbc Latin1_General_CI_AI 编码

0 投票
1 回答
636 浏览
提问于 2025-04-18 14:47

我有一个使用Django的应用程序,它通过pyodbc与一个MS SQL Server数据库进行通信,这个数据库的编码是Latin1_General_CI_AI。(我无法控制这个数据库,也不能更改它的编码。)

问题是,从Django到pyodbc的每个字符串都必须进行编码:

举个例子:

m = MyModel()
m.foo = 'foo' # Garbage characters are saved
m.foo = 'foo'.encode('latin1') # String is saved correctly
m.save()

第二个问题是查询字符串也需要编码:

MyModel.objects.get(name=name) # fails
MyModel.objects.get(name=name.encode('latin1')) # works

有没有更通用的方法可以处理这个问题?比如说使用模型混入或者数据库后端?我在Django的SQLCompiler中看到了一些地方,但不太确定怎么去影响它。

1 个回答

0

我之前也遇到过类似的问题,并且找到了一个类似的解决办法。

对我来说,添加连接参数 ClientCharset=utf8 解决了这个问题。如果你像我一样使用 django-pyodbc,那么你需要在数据库配置设置中添加: 'OPTIONS': { 'extra_params': 'ClientCharset=utf8', } 如果你直接使用 pyodbc,那么只需把这个参数加到你的连接字符串里就可以了。

根据我的理解,这里有个关键点,就是你的 TDS 驱动程序已经在尝试将源数据库的数据转换成适合你客户端读取的默认编码。因为我们是在微软的环境下,适合的默认编码是 ISO 8859-1(我记不太清楚这是不是完全等同于 Latin-1,或者只是非常接近,以至于人们通常不会注意到区别)。这就是为什么你的解决办法有效的原因。想了解更多,可以查看 这里

Django 期望数据库使用 utf-8 编码进行交流,所以我们只需要告诉 TDS 驱动程序我们想要的编码格式。

撰写回答