2016-07-18 24 views
1

Ich verwende pyodbc (ich fürchte, ich weiß nicht, welche Version) in Kombination mit MS Access und Python 3.2.5.Unicode utf-16/8 Chaos mit pyodbc

ODBC Version ist unixODBC 2.2.14, mdb Fahrer msodbcsql-11.0.2270 auf einem RHEL6 System

Nun ist die große Frage ist, dass, wenn ich versuche und meine Tabelle abfragen, es die Werte in Kauderwelsch zurückgibt.

Beispiel, SELECT * FROM table kehrt:

('ä¹ã', 'ã¶ã°ã°ã°ãµã°') 

Jetzt selbst das ist kein großes Problem, ich kann es nur kodieren, können eigene Zeichenketten Kodierungsverfahren mit Python.

def _enc16(self, value): 
     return value.encode('utf-16')[2::] 

Obwohl ich den ODBC-Treiber zu sagen, dass ich utf-16 verwendet werden soll (ich dachte, das war Python Standard?)

Auszug aus meinem odbc.ini:

[mdb] 
Description = Microsoft Access 
Driver = MDBToolsODBC 
Database = /path/to/file.mdb 
Servername = localhost 
Charset = UTF16 
PORT = 5432 

Jetzt beginnen die Probleme. Wenn ich versuche, die Tabelle mithilfe von WHERE-Klauseln abzufragen, kann meine Python-Zeichenfolge höchstwahrscheinlich nicht mit dem Tabelleninhalt verglichen werden, da sie unterschiedlich codiert sind.

So SELECT * FROM table WHERE id = '1' gibt None zurück, obwohl es einen entsprechenden Datensatz gibt (ich habe die Anweisung in Access kopiert und der Datensatz gefunden).

Was ist der beste Ansatz hier? Konfigurieren Sie ODBC so, dass es die korrekte Kodierung zurückgibt (wie? Ich spiele schon eine Weile damit herum) oder kodiere meine Suchkriterien (indem ich '1' in 'ä¹ã' umwandel, aber wie?)?

Danke für Ihre Hilfe!

Antwort

1

Ok, also löste ich es mit der SELECT * FROM table Anweisung und fütterte die Ergebnisse in eine Liste von Listen. Ich habe eine einfache Suche über diese Liste durchgeführt, um den eindeutigen Datensatz herauszufiltern, nach dem ich suche. Ich weiß, das ist ein bisschen langweilig, aber es funktioniert.

rows = [[b'' if value is None else self._enc16(value) for value in row] for row in cursor.fetchall()] 

for row in rows: 
    for i, entry in enumerate(row): 
    row[i] = str(self._dec8(entry)) 
    if row[0] == str(samplenr): 
    break 

Wie Sie sehen können, löste ich die Codierung Problem, indem die verschlüsselten Ergebnisse mit UTF-16-Codierung und reencoding sie auf UTF-8 so Python kann es in eine lesbare Zeichenfolge drehen.