Кодирование звонков с pyodbc на MS SQL Server - PullRequest
4 голосов
/ 20 сентября 2010

Я подключаюсь к серверу MS SQL через SQL Alchemy, используя модуль pyodbc. Кажется, все работает нормально, пока у меня не возникли проблемы с кодировками. Некоторые символы, отличные от ascii, заменяются на «?»

БД имеет параметры сортировки 'Latin1_General_CI_AS' (я проверил также определенные поля, и они сохраняют те же параметры сортировки). Я начал выбирать кодировку 'latin1' в вызове create_engine, и это, кажется, работает для западноевропейских символов (например, французского или испанского, например, é), но не для пасхально-европейских символов. Конкретно у меня проблема с персонажем ć

Я пытался выбрать другие кодировки , как указано в документации Python , в частности, Microsoft, например cp1250 и cp1252, но я продолжаю сталкиваться с той же проблемой.

Кто-нибудь знает, как решить эти различия? Имеет ли сопоставление Latin1_General_CI_AS эквивалентность кодировкам Python?

Код моего текущего соединения:

for sqlalchemy import *

def connect():
    return pyodbc.connect('DSN=database;UID=uid;PWD=password')

engine = create_engine('mssql://', creator=connect, encoding='latin1')
connection = engine.connect()

Разъяснения и комментарии:

  • Эта проблема возникает при получении информации из БД. Мне не нужно ничего хранить.
  • В начале я не указывал кодировку, и в результате получалось, что всякий раз, когда в БД встречается символ не ascii, pyodbc вызывает UnicodeDecodeError. Я исправил это, используя 'latin1' в качестве кодировки, но это не решает проблему для всех символов.
  • Я признаю, что сервер не на латинице 1, комментарий неверный. Я проверял как параметры сортировки базы данных, так и параметры конкретных полей, и похоже, что все они в 'Latin1_General_CI_AS', тогда как можно сохранить ć? Может быть, я не правильно понимаю сопоставления.
  • Я немного исправил вопрос, в частности, я пробовал больше кодировок, чем latin1, а также cp1250 и cp1252 (который, по-видимому, используется в 'Latin1_General_CI_AS', согласно msdn)

UPDATE:

ОК, после этих шагов я получаю, что кодировка, используемая БД, выглядит как cp1252: http://bytes.com/topic/sql-server/answers/142972-characters-encoding Во всяком случае, это кажется плохим предположением, отраженным в ответах.

UPDATE2: В любом случае, после правильной настройки драйвера odbc мне не нужно указывать кодировку в коде Python.

Ответы [ 4 ]

2 голосов
/ 20 сентября 2010

Исходный комментарий превратился в ответ:

cp1250 и cp1252 НЕ являются "кодировками latin1".Сличение - это не кодировка.Re ваш комментарий: кто говорит, что "сервер закодирован в latin1"?Если сервер ожидает, что весь ввод / вывод будет закодирован в латинице 1 (в чем я сомневаюсь), то вы просто не сможете вставить некоторые восточноевропейские символы в вашу базу данных (ни русский, ни китайский, ни греческий и т. Д.).

Обновление :

Вы должны смотреть дальше, чем сопоставление.msgstr "" "msdn.microsoft.com/en-us/library/ms174596(v=SQL.90).aspx предполагает, что для Latin1_General_CI_AS используемая кодировка - cp1252" "" - codswallop.В таблице указаны LCID (идентификатор локали), сопоставление по умолчанию и кодовая страница для каждой локали.Да, сортировка "Latin1_General_CI_AS" указана в связи с кодовой страницей cp1252 для нескольких локалей.Для двух локалей (армянский и грузинский) он указан вместе с кодовой страницей «Юникод» (!!!).

Проще говоря, вам необходимо выяснить, что кодовая страница база данныхиспользует.

Попробуйте извлечь данные из базы данных без указания кодировки вообще. Не беспокойтесь о кодировке, которая, как вы думаете, может использоваться вашей консолью - это только добавляет еще один источник путаницы.Вместо этого используйте print repr(data).Сообщите здесь, что вы получаете от repr (), где вы ожидаете не латинские символы 1.

2 голосов
/ 20 сентября 2010

Вам следует прекратить использовать кодовые страницы и переключиться на Unicode. Это единственный способ избавления от подобных проблем.

1 голос
/ 20 сентября 2010

Попробуйте подключиться к БД с помощью параметра pyodbc.connect () convert_unicode=True, например. из sqlalchemy:

engine = create_engine('mssql://yourdb', connect_args={'convert_unicode': True})

Это должно гарантировать, что все результаты (а не только результаты nvarchar и т. Д.), Которые вы получите, являются Unicode, правильно преобразованы из любой кодировки, используемой в БД.

Что касается записи в БД, просто всегда используйте Юникод. Если я не ошибаюсь (проверим позже), pyodbc позаботится о том, чтобы он также правильно записывался в БД.

(конечно, если БД использует кодировку, которая не поддерживает символы, которые вы хотите написать, вы по-прежнему будете получать ошибки: если вы хотите, чтобы столбцы поддерживали любой тип символов, вам придется использовать столбцы Unicode на БД тоже)

0 голосов
/ 20 сентября 2010

ОК, для http://msdn.microsoft.com/en-us/library/ms174596(v=SQL.90).aspx кодировка Latin1_General_CI_AS, скорее всего, cp1252.Итак, вам придется использовать encoding='cp1252'.Но это может решить только половину проблемы, потому что у вас есть , чтобы каким-то образом вывести значения, чтобы увидеть, присутствуют ли символы или нет.Так что, если у вас есть some_db_value, который вы извлекли из базы данных, вам нужно some_db_value.encode('proper-output-encoding'), чтобы иметь это право.proper-output-encoding зависит от того, как вы выводите это: на консоли это кодировка консоли, которая может быть любой, например, «cp1252», «cp437», «cp850» (в Windows).В Интернете это кодировка веб-сервера, мы надеемся, что 'utf-8'.

edit: Пожалуйста, прочитайте Ответ Джона Мачина , так как не clearявляется ли 'cp1252' правильной кодировкой базы данных

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...