Latin-1 и фабрика юникодов в Python
У меня есть сценарий Python 2.6, который заглатывает специальные символы, закодированные в Latin-1, которые я получаю из базы данных SQL Server. Я хотел бы напечатать эти символы, но я несколько ограничен, потому что я использую библиотеку, которая вызываетunicode
фабрика, и я не знаю, как заставить Python использовать кодек, отличный отascii
.
Сценарий - это простой инструмент для возврата данных поиска из базы данных без необходимости выполнения SQL непосредственно в редакторе SQL. Я используюPrettyTable 0,5 библиотека для отображения результатов.
Ядро скрипта - это бит кода. Кортежи, которые я получаю от курсора, содержат целочисленные и строковые данные, а не данные Unicode. (Я используюadodbapi
вместоpyodbc
, что бы получить Unicode, ноadodbapi
дает мне другие проблемы.)
x = pyodbc.connect(cxnstring)
r = x.cursor()
r.execute(sql)
t = PrettyTable(columns)
for rec in r:
t.add_row(rec)
r.close()
x.close()
t.set_field_align("ID", 'r')
t.set_field_align("Name", 'l')
print t
НоName
столбец может содержать символы, которые выходят за пределы диапазона ASCII. Иногда я получаю сообщение об ошибке, подобное этому, в строке 222prettytable.pyc
когда дело доходит доt.add_row
вызов:
UnicodeDecodeError: 'ascii' codec can't decode byte 0xed in position 12: ordinal not in range(128)
Это строка 222 вprettytable.py
, Оно используетunicode
, который является источником моих проблем, и не только в этом скрипте, но и в других скриптах Python, которые я написал.
for i in range(0,len(row)):
if len(unicode(row[i])) > self.widths[i]: # This is line 222
self.widths[i] = len(unicode(row[i]))
Пожалуйста, скажите мне, что я здесь делаю неправильно. Как я могу сделатьunicode
работать без взломаprettytable.py
или любые другие библиотеки, которые я использую? Есть ли способ сделать это?
РЕДАКТИРОВАТЬ: ошибка возникает не вprint
заявление, но наt.add_row
вызов.
РЕДАКТИРОВАТЬ: С помощью Бастиена Лендера я нашел следующее решение. Это не панацея, но это работает.
x = pyodbc.connect(cxnstring)
r = x.cursor()
r.execute(sql)
t = PrettyTable(columns)
for rec in r:
urec = [s.decode('latin-1') if isinstance(s, str) else s for s in rec]
t.add_row(urec)
r.close()
x.close()
t.set_field_align("ID", 'r')
t.set_field_align("Name", 'l')
print t.get_string().encode('latin-1')
В итоге мне пришлось декодировать при входе и кодировать при выходе. Все это заставляет меня надеяться, что все перенесут свои библиотеки в Python 3.x раньше, чем позже!