#python #python-2.7 #encode #pyodbc #netezza
#python #python-2.7 #кодировать #pyodbc #netezza
Вопрос:
NVARCHAR
В моей базе данных есть столбец типа. Я не могу преобразовать содержимое этого столбца в простую строку в своем коде. (Я использую pyodbc
для подключения к базе данных).
# This unicode string is returned by the database
>>> my_string = u'u4157u4347u6e65u6574u2d72u3430u3931u3530u3731u3539u3533u3631u3630u3530u3330u322du3130u3036u3036u3135u3432u3538u2d37u3134u3039u352d'
# prints something in chineese
>>> print my_string
䅗䍇湥整㐰㤱㔰㜱㔹㔳㘱㘰㔰㌰㈭〶〶ㄵ㐲㔸ⴷㄴ〹㔭
Самое близкое, что я сделал, — это кодирование его utf-16
как:
>>> my_string.encode('utf-16')
'xffxfeWAGCenter-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
.
Редактировать: при преобразовании его в utf-16-le
я могу удалить ненужные символы из начала, но все же один символ отсутствует в конце
>>> print t.encode('utf-16-le')
WAGCenter-04190517953516060503-20160605124857-4190-5
При попытке найти некоторые другие столбцы он работает. Что может быть причиной этой прерывистой проблемы?
Комментарии:
1. Вы видите метку порядка байтов (спецификация)
2. @brianpck Знак порядка байтов в начале пропущенный 1 в конце. Я сейчас расследую вопрос о метке порядка байтов . Есть идеи, почему
1
отсутствует в last?3.Символы в
my_string
являются кодовыми точками cjk, так что вряд ли это будет то, что на самом деле возвращается изnvarchar
поля? Если возможно, всегда можно прочитать его как avarchar
с приведениемselect cast(field as varchar(xxx)) ...
4. Спецификация добавлена кодеком ‘utf-16’ и маловероятна в необработанных данных.
5. @AlexK. : Мой запрос похож
SELECT UNIQUE(MY_ID) FROM MY_TABLE;
и при печатиresultset
я получаю[(u'u4157u4347u6e65u6574u2d72u3430u3931u3530u3731u3539u3533u3631u3630u3530u3330u322du3130u3036u3036u3135u3432u3538u2d37u3134u3039u352d', )]
Ответ №1:
У вас серьезная проблема в определении вашей базы данных, в том, как вы храните в ней значения или в том, как вы считываете из нее значения. Я могу только объяснить, что вы видите, но ни почему, ни как это исправить без:
- тип базы данных
- способ ввода в него значений
- способ извлечения значений для получения вашей псевдо-строки в юникоде
- фактическое содержимое, если вы используете прямой (собственный) доступ к базе данных
То, что вы получаете, — это строка ASCII, где 8-битные символы сгруппированы по парам для построения 16-битных символов Юникода в порядке наименьшего конца. Поскольку ожидаемая строка содержит нечетное количество символов, последний символ был (безвозвратно) потерян при переводе, потому что исходная строка заканчивается на u'352d'
где 0x2d — код ASCII для '-'
и 0x35 для '5'
. ДЕМОНСТРАЦИЯ:
def cvt(ustring):
l = []
for uc in ustring:
l.append(chr(ord(uc) amp; 0xFF)) # low order byte
l.append(chr((ord(uc) >> 8) amp; 0xFF)) # high order byte
return ''.join(l)
cvt(my_string)
'WAGCenter-04190517953516060503-20160605124857-4190-5'
Комментарии:
1. Я признаю, что это не отвечает на вопрос, но это лучшее, что я могу сделать с данной информацией, и это слишком подробно для комментария
2. Я использую
Netezza
в качестве ядра базы данных. и я не могу его закодироватьascii
. Я настроил свойpyodbc
дляutf-16
. Дайте мне знать, какие дополнительные сведения вам нужны? Спасибо за объяснение. Я знаю, что что-то не так, но я не знаю, где проверить. Кроме того, эта база данных, которую я использую, принадлежит другой команде, я могу изменить конфигурацию только на уровне моего проекта.3. @user7001260: не могли бы вы настроить pyodbc для кодировки latin1? Latin1 содержит только 256 первых кодов Юникода.
Ответ №2:
Проблема заключалась в том, что я использовал UTF-16
в своем odbcinst.ini
файле where, поскольку мне приходилось использовать UTF-8
формат кодировки символов.
Ранее я менял его как OPTION
параметр при подключении PyODBC
. Но позже изменение его в odbcinst.ini
файле устранило проблему.