Latin-1 i fabryka Unicode w Pythonie

Mam skrypt Pythona 2.6, który dławi się na znaki specjalne, zakodowane w Latin-1, które pobieram z bazy danych SQL Server. Chciałbym wydrukować te znaki, ale jestem nieco ograniczony, ponieważ używam biblioteki, która wywołujeunicode i nie wiem, jak sprawić, by Python używał kodeka innego niżascii.

Skrypt jest prostym narzędziem do zwracania danych wyszukiwania z bazy danych bez konieczności wykonywania SQL bezpośrednio w edytorze SQL. używamPrettyTable 0,5 biblioteki do wyświetlania wyników.

Rdzeniem skryptu jest ten fragment kodu. Krotki, które otrzymuję od kursora, zawierają dane całkowite i łańcuchowe oraz dane Unicode. (Użyłbymadodbapi zamiastpyodbc, co dałoby mi Unicode, aleadodbapi daje mi inne problemy.)

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

AleName kolumna może zawierać znaki spoza zakresu ASCII. Czasem otrzymam komunikat o błędzie podobny do tego w linii 222prettytable.pyc, kiedy dotrze dot.add_row połączenie:

UnicodeDecodeError: 'ascii' codec can't decode byte 0xed in position 12: ordinal not in range(128)

To jest linia 222 wprettytable.py. To używaunicode, co jest źródłem moich problemów, nie tylko w tym skrypcie, ale w innych skryptach Pythona, które napisałem.

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]))

Proszę mi powiedzieć, co tu źle robię. Jak mogę to zrobićunicode pracować bez hakowaniaprettytable.py lub jakiejkolwiek innej biblioteki, z której korzystam? Czy jest na to jakiś sposób?

EDYCJA: Błąd nie występuje wprint oświadczenie, ale nat.add_row połączenie.

EDIT: Z pomocą Bastiena Léonarda wymyśliłem następujące rozwiązanie. To nie jest panaceum, ale działa.

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')

Skończyło się na tym, że musiałem dekodować po drodze i kodować w drodze wyjścia. Wszystko to sprawia, że ​​mam nadzieję, że wszyscy porowią swoje biblioteki do Pythona 3.x wcześniej niż później!

questionAnswers(3)

yourAnswerToTheQuestion