Python pymssql在Azure/Windows上返回的字符集与在Mac上返回的不同

Python pymssql在Azure/Windows上返回的字符集与在Mac上返回的不同,python,azure,character-encoding,pymssql,Python,Azure,Character Encoding,Pymssql,我有一个托管在Azure上的sql server数据库。我在数据库中放入了一个带智能引号的字符串(“test”)。我可以连接到它并运行一个简单的查询: import pymssql import json conn = pymssql.connect( server='coconut.database.windows.net', user='kingfish@coconut', password='********', database='coconut',

我有一个托管在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应用程序服务)上运行此查询时,我得到了同一字符串的不同(且不正确)编码:

"\u0093test\u0094"
我在pymssql连接上将字符集指定为“UTF-8”。为什么Windows/Azure环境返回不同的字符集


(注意:我已经将预先构建的二进制pymssql-2.1.3-cp34-none-win32.whl放在Azure上我的项目repo的驾驶室中。这与PyPI上预先构建的二进制pymssql-2.1.3-cp34-cp34m-win32.whl相同,只是我不得不将“cp34m”重命名为“none”以说服pip安装它。)

根据您的描述,我认为问题似乎是由Azure上SQL数据库的默认字符集编码引起的。为了验证我的想法,我在Python3中做了一些测试

Azure上SQL数据库的默认字符集编码为


Microsoft Azure SQL数据库使用的默认数据库排序规则是SQL\u LATIN1\u GENERAL\u CP1\u CI\u AS,其中LATIN1\u GENERAL是英语(美国),CP1是代码页1252,CI不区分大小写,AS区分重音。无法更改V12数据库的排序规则。有关如何设置排序规则的详细信息,请参阅COLLATE(Transact-SQL)

如上图所示,可以通过encode
\u201c
&
\u0093
\u0094
获取
\u201d

以及

因此,我认为当前用于数据存储的SQL数据库的字符集编码是
Latin-1
,而不是
UTF-8
,当您创建SQL数据库时,如下图所示,Azure portal上的默认属性
排序规则是
SQL\u Latin1\u General\u CP1\u CI\u as
。请尝试使用其他排序规则支持
UTF-8
,而不是默认的排序规则支持


根据您的描述,我认为问题似乎是由Azure上SQL数据库的默认字符集编码引起的。为了验证我的想法,我在Python3中做了一些测试

Azure上SQL数据库的默认字符集编码为


Microsoft Azure SQL数据库使用的默认数据库排序规则是SQL\u LATIN1\u GENERAL\u CP1\u CI\u AS,其中LATIN1\u GENERAL是英语(美国),CP1是代码页1252,CI不区分大小写,AS区分重音。无法更改V12数据库的排序规则。有关如何设置排序规则的详细信息,请参阅COLLATE(Transact-SQL)

如上图所示,可以通过encode
\u201c
&
\u0093
\u0094
获取
\u201d

以及

因此,我认为当前用于数据存储的SQL数据库的字符集编码是
Latin-1
,而不是
UTF-8
,当您创建SQL数据库时,如下图所示,Azure portal上的默认属性
排序规则是
SQL\u Latin1\u General\u CP1\u CI\u as
。请尝试使用其他排序规则支持
UTF-8
,而不是默认的排序规则支持


我最终将列类型从VARCHAR重新编译为NVARCHAR。这就解决了我的问题,不管平台如何,字符都能正确解释。

我最终将列类型从VARCHAR重新编译为NVARCHAR。这就解决了我的问题,无论平台如何,字符都能正确解释。

很有趣。我使用的是SQL拉丁1\u General\u CP1\u CI\u AS的默认排序规则。当我在Mac上运行“sys.stdin.encoding”时,我得到了“utf-8”,在Azure上我得到了“cp1252”。我想知道默认的python字符编码是否决定了所使用的unicode字符。只是在Azure发布Python之前,我不知道如何在Azure上执行“chcp 65001”…很有趣。我使用的是SQL拉丁1\u General\u CP1\u CI\u AS的默认排序规则。当我在Mac上运行“sys.stdin.encoding”时,我得到了“utf-8”,在Azure上我得到了“cp1252”。我想知道默认的python字符编码是否决定了所使用的unicode字符。只是在Azure发布Python之前,我不知道如何在Azure上执行“chcp 65001”…太棒了。谢谢你的分享。太好了。谢谢分享。
>>> u"\u201c".encode('cp1252')
b'\x93'
>>> u"\u201d".encode('cp1252')
b'\x94'
>>> 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