pymssql возвращает другую кодировку в Azure/Windows, чем на Mac

У меня есть база данных сервера sql, размещенная в Azure. Я поместил строку в базу данных с умными кавычками («тест»). Я могу подключиться к нему и запустить простой запрос:

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 (Python 3.4, служба приложений Azure), я получаю другую (и неправильную) кодировку для той же строки:

"\u0093test\u0094"

Я указал кодировку как «UTF-8» в соединении pymssql. Почему среда Windows/Azure возвращает другую кодировку?

(примечание: я поместил предварительно созданный двоичный файл pymssql-2.1.3-cp34-none-win32.whl в рулевую рубку репозитория моего проекта в Azure. Это то же самое, что и предварительно созданный двоичный файл pymssql pymssql-2.1.3. -cp34-cp34m-win32.whl только на PyPI мне пришлось переименовать «cp34m» в «none», чтобы убедить pip установить его.)


person Wheat    schedule 23.10.2016    source источник


Ответы (2)


Согласно вашему описанию, мне кажется, что проблема была вызвана кодировкой по умолчанию для базы данных SQL в Azure. Чтобы проверить свою мысль, я провел несколько тестов ниже в Python 3.

Кодировка по умолчанию для базы данных SQL в Azure — Windows-1252 (CP-1252).

Поддержка сортировки SQL Server
Сопоставление базы данных по умолчанию, используемое базой данных 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 для хранения данных — Latin-1, а не UTF-8, когда вы создали базу данных SQL, как показано на рисунке ниже, свойство по умолчанию Collation на портале Azure — SQL_Latin1_General_CP1_CI_AS. Пожалуйста, попробуйте использовать другую поддержку сортировки UTF-8 вместо стандартной.

введите описание изображения здесь

person Peter Pan    schedule 24.10.2016
comment
Интересно. Я использую сопоставление по умолчанию SQL_Latin1_General_CP1_CI_AS . Когда я запускаю sys.stdin.encoding на своем Mac, я получаю utf-8, а в Azure я получаю cp1252. Интересно, определяет ли кодировка символов python по умолчанию используемые символы Unicode. Только не могу сообразить, как сделать chcp 65001 на Azure до того, как он запустит Python... - person Wheat; 25.10.2016

В итоге я изменил тип столбца с VARCHAR на NVARCHAR. Это решило мою проблему, символы интерпретируются правильно, независимо от платформы.

person Wheat    schedule 26.10.2016
comment
Большой. Спасибо, что поделились. - person Peter Pan; 03.11.2016