2016-10-11 20 views
5

У меня есть столбец NVARCHAR в моей базе данных. Я не могу преобразовать содержимое этого столбца в обычную строку в моем коде. (Я использую pyodbc для подключения к базе данных).Ошибка кодирования/декодирования строки - отсутствующий символ с конца

# This unicode string is returned by the database 
>>> my_string = u'\u4157\u4347\u6e65\u6574\u2d72\u3430\u3931\u3530\u3731\u3539\u3533\u3631\u3630\u3530\u3330\u322d\u3130\u3036\u3036\u3135\u3432\u3538\u2d37\u3134\u3039\u352d' 

# prints something in chineese 
>>> print my_string 
䅗䍇湥整⵲㐰㤱㔰㜱㔹㔳㘱㘰㔰㌰㈭㄰〶〶ㄵ㐲㔸ⴷㄴ〹㔭 

Ближайший я пошел осуществляется через кодирующий его utf-16 как:

>>> my_string.encode('utf-16') 
'\xff\xfeWAGCenter-04190517953516060503-20160605124857-4190-5' 
>>> print my_string.encode('utf-16') 
��WAGCenter-04190517953516060503-20160605124857-4190-5 

Но фактическое значение, что мне нужно, как в магазине значений в базе данных:

WAGCenter-04190517953516060503-20160605124857-4190-51 

Я пробовал с кодировкой до utf-8, utf-16, ascii, utf-32, но ничего не работало.

У кого-нибудь есть идея относительно того, чего я не хватает? И как получить желаемый результат от my_string.

Edit: На превращение его в utf-16-le, я могу удалить ненужные символы из начала, но еще один символ отсутствует конец

>>> print t.encode('utf-16-le') 
WAGCenter-04190517953516060503-20160605124857-4190-5 

На попытке некоторых других столбцов, то работает. Что может быть причиной этой прерывистой проблемы?

+0

Вы видите знак байта (BOM) – brianpck

+0

@brianpck Значок порядка байтов в начале + отсутствует 1 в конце. Сейчас я изучаю * Байт-порядок *. Любая идея, почему «1» отсутствует последним? – user7001260

+1

Символы в 'my_string' * - это кодовые точки cjk, так что вряд ли они вернутся из поля' nvarchar'? Если возможно, всегда можно прочитать его как «varchar» с литым выбором select (поле как varchar (xxx)) ... ' –

ответ

2

У вас возникли серьезные проблемы с определением базы данных в том, как вы храните в ней значения, или в том, как вы читаете значения из него. Я могу только объяснить, что вы видите, но ни почему, ни как это исправить без:

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

Wh у вас есть строка ASCII, где 8-битные символы сгруппированы по паре для построения 16-разрядных символов юникода в маленьком концевом порядке. Поскольку ожидаемая строка имеет нечетные числа символов, последний символ (без потерь) терялся в переводе, потому что исходная строка заканчивается u'\352d', где 0x2d - код ASCII для '-' и 0x35 для '5'. Демонстрация:

def cvt(ustring): 
    l = [] 
    for uc in ustring: 
     l.append(chr(ord(uc) & 0xFF)) # low order byte 
     l.append(chr((ord(uc) >> 8) & 0xFF)) # high order byte 
    return ''.join(l) 

cvt(my_string) 
'WAGCenter-04190517953516060503-20160605124857-4190-5' 
+0

Я признаю, что это не отвечает на вопрос, но это лучшее, что я могу сделать с данными, и он слишком разработан для комментария –

+0

Я использую 'Netezza' как механизм базы данных. и я не могу закодировать его на 'ascii'. Я настроил свой 'pyodbc' для' utf-16'. Дайте мне знать, какие дополнительные данные вам нужны? Спасибо за объяснение. Я знаю, что что-то не так, но я не знаю, где проверить. Кроме того, эта база данных, которую я использую, принадлежит другой команде, я могу только изменить конфигурацию на моем уровне проекта. – user7001260

+0

@ user7001260: Вы могли бы настроить pyodbc для кодирования latin1? Latin1 просто содержит 256 первых кодов юникода. –

1

Этот вопрос, я использовал UTF-16 в моем odbcinst.ini файл, в котором я должен был использовать UTF-8 формат кодировки символов.

Раньше я менял его как параметр OPTION при подключении к PyODBC. Но позже, изменив его в файле odbcinst.ini, исправлена ​​проблема.

 Смежные вопросы

  • Нет связанных вопросов^_^