SQL Server (SQLCMD), проблема с Python и кодированием при использовании символов не ascii - PullRequest
3 голосов
/ 03 ноября 2011

Я сталкиваюсь с проблемой кодировки моего кода Python при запросе данных, которые есть в SQL Server 2005.

(потому что я не смог скомпилировать PyMSSQL-2.0.0b1 )Я использую этот фрагмент кода , и я могу сделать некоторые выборки, но теперь я придерживаюсь вопроса, что я не знаю, что выводит мне SQLCMD: (

(мне пришлось работать с европейским языком, содержащимся в таблице, поэтому мне пришлось столкнуться с другими кодировками с акцентом и т. д.)

например:

  • когда я читаю его (выбираю) в Ms SQLServer Management Studio, у меня появляется название этой страны: «Ceská republika» (обратите внимание, что первая буква «a» написана острым шрифтом)
  • при использовании его из SQLCMD из командной строки (Powershell в Windows 7) все еще в порядке, я вижу «Cesk'a с острым»
  • теперь при использовании Python с уловкой os.popen из рецепта , то есть со следующей строкой соединения:

    sqlcmd -U adminname -P пароль -S имя_сервера -d dbname / w 8192 -u

я получаю эту строку: 'Cesk \ xa0 republika'

обратите внимание на \ xa0, что я знаю, что это за кодировка и как я могу перейти от этого \ xa0 к {a с острым} ...

, если я тестирую из Python, и Unicode, я долженесть этот '\ xe1'

>>> unicode('Cesk\xa0 republika')

Traceback (most recent call last):
  File "<pyshell#13>", line 1, in <module>
    unicode('Cesk\xa0 republika')
UnicodeDecodeError: 'ascii' codec can't decode byte 0xa0 in position 4: ordinal not in range(128)

>>> unicode_a_with_acute = u'\N{LATIN SMALL LETTER A WITH ACUTE}'
>>> unicode_a_with_acute
u'\xe1'
>>> print unicode_a_with_acute
á
>>> print unicode_a_with_acute.encode('cp1252')
á
>>> unicode_a_with_acute.encode('cp1252')
'\xe1'
>>> print 'Cesk\xa0 republika'.decode('cp1252')
Cesk  republika
>>> print 'Cesk\xa0 republika'.decode('utf8')

Traceback (most recent call last):
  File "<pyshell#21>", line 1, in <module>
    print 'Cesk\xa0 republika'.decode('utf8')
  File "C:\Python27\lib\encodings\utf_8.py", line 16, in decode
    return codecs.utf_8_decode(input, errors, True)
 UnicodeDecodeError: 'utf8' codec can't decode byte 0xa0 in position 4: invalid start byte

, так что же мне дает SQLCMD?Как мне заставить его и / или os.popen и других быть уверенными, что у меня есть понятный utf8 для Python?

(обратите внимание, я пробовал как с, так и без окончания на -s на os.popen cmdдля SQLCMD и это должно означать просьбу к SQLCMD ответить в юникоде, без эффекта, также я попытался передать его строкой "select" python, закодированной в utf8, но безуспешно:

 sqlstr = unicode('select * from table_pays where country_code="CZ"')
 cu = c.cursor
 lst = cu.execute(sqlstr)
 rows = cu.fetchall()
 for x in rows:
      print x

 ( 'CZ          ', 'Cesk\xa0 republika       ')

)

еще один момент: из того, что я googl-ed, о "sqlcmd.exe", есть также эти параметры, которые могут помочь:

[ -f < codepage > | i: < codepage > [ < , o: < codepage > ] ]

, но я не смог указатьправильный, я не знаю, каковы возможные значения, кстати, используя (или не используя):

[ -u unicode output]

мне тоже не поможет ...

Ответы [ 2 ]

0 голосов
/ 14 ноября 2011

Похоже, ваша кодовая страница по умолчанию - 850 или 437. Никогда не пытайтесь угадать на кодовых страницах: chcp в командной строке скажет вам, что ваша система настроена на использование.

Попытка установить командуКодовая страница процессора с chcp или mode con: вряд ли будет полезна, поскольку они устанавливают выходную кодовую страницу для консоли, а не для пипсов или перенаправления в файл.

Для получения Unicode (или, скорее, utf-16)) вывод в трубе использует cmd /u:

>>> subprocess.check_output('''cmd /u /c "echo hello\xe1"''').decode('utf16')
'helloá\r\n'
>>> 

Но вам почти наверняка будет лучше просто установить настоящий адаптер базы данных.

0 голосов
/ 11 ноября 2011

Проблема может заключаться в том, что консоль по умолчанию работает в режиме ascii и вывод преобразуется через текущую настройку кодовой страницы. Вы можете попробовать следующее, либо написать результат отделить файл с помощью: -o -u

Тогда файл результатов будет иметь правильную кодировку ucs2, которую с удовольствием принимает python. Другая для настройки вывода консоли utf8 (не проверено):

# setup utf8 on windows console
cmode = 'mode con: codepage select=65001 > NUL & '
cmd = 'my command'
f = os.popen(cmode + cmd)
out = f.readlines()
...