我在Azure上托管了一个sql server数据库。我在数据库中放了一个带有智能引号的字符串('“test”')。我可以连接到它并运行一个简单的查询:
import pymssql
import json
conn = pymssql.connect(
server='coconut.database.windows.net',
user='kingfish@coconut',
password='********',
database='coconut',
charset='UTF-8',
)
sql = """
SELECT * FROM messages WHERE id = '548a72cc-f584-7e21-2725-fe4dd594982f'
"""
cursor = conn.cursor()
cursor.execute(sql)
row = cursor.fetchone()
json.dumps(row[3])
当我在Mac上运行此查询(macOS 10.11.6,Python 3.4.4,pymssql 2.1.3)时,我找回了字符串:
"\u201ctest\u201d"
这被正确解释为智能引号并正确显示。
当我在Azure Web部署(Python 3.4,Azure App服务)上运行此查询时,我得到了相同字符串的不同(和不正确)编码:
"\u0093test\u0094"
我在pymssql连接上将charset指定为'UTF-8'。为什么Windows / Azure环境会返回不同的字符集?
(注意:我已将预先构建的二进制文件pymssql-2.1.3-cp34-none-win32.whl放在我的项目仓库的驾驶室中。这与pymssql预构建的二进制文件pymssql-相同在PyPI上只有2.1.3-cp34-cp34m-win32.whl我必须将'cp34m'重命名为'none'以说服pip安装它。)
答案 0 :(得分:2)
根据您的描述,我认为该问题似乎是由Azure上SQL数据库的默认字符集编码引起的。为了验证我的想法,我在Python 3中做了一些测试。
Azure上SQL数据库的默认字符集编码为Windows-1252 (CP-1252)。
SQL Server Collation Support
Microsoft Azure SQL数据库使用的默认数据库归类是SQL_LATIN1_GENERAL_CP1_CI_AS,其中LATIN1_GENERAL是英语(美国), CP1是代码页1252 ,CI是不区分大小写的,AS是重音敏感的。无法更改V12数据库的排序规则。有关如何设置排序规则的详细信息,请参阅COLLATE(Transact-SQL)。
>>> u"\u201c".encode('cp1252')
b'\x93'
>>> u"\u201d".encode('cp1252')
b'\x94'
如上所示代码,\u0093
& \u0094
可以通过编码\u201c
& \u201d
。
和
>>> u"\u0093".encode('utf-8')
b'\xc2\x93'
>>> u"\u0093".encode('utf-8').decode('cp1252')[1]
'“' # It's `\u201c`
>>> u"\u201c" == u"\u0093".encode('utf-8').decode('cp1252')[1]
True
因此,当您创建SQL数据库时,我认为当前用于数据存储的SQL数据库的charset编码为Latin-1
,而不是UTF-8
,如下图所示,默认属性{{1} Azure门户上的Collation
。请尝试使用其他归类支持SQL_Latin1_General_CP1_CI_AS
而不是默认支持。
答案 1 :(得分:1)
我最终将列类型从VARCHAR重新编辑为NVARCHAR。这解决了我的问题,无论平台如何,都能正确解释字符。