2016-05-10 16 views
1

Ich weiß, es wurde mehrmals gefragt, aber keiner der Antwort gab mir eine LösungUnicodeEncodeError: 'Ascii' Codec kann nicht codieren Zeichen u ' xe9' in Position 54: Ordnungszahl nicht im Bereich (128)

Hier

ist der Code (Python 2.7):

import cx_Oracle 
import pandas as pd 

connstr = 'MyConstr' 
conn = cx_Oracle.connect(connstr) 
cur = conn.cursor() 

xl = pd.ExcelFile("C:\\TEMP\\for_kkod.xlsx") 
df = xl.parse(0) 

for i in df.index: 
    s = u"insert into MY_TABLE values({0}, '{1}')".format(int(df.iloc[i]['kkod']), df.iloc[i]['kkodnev']) 
    print s 
    print type(s) 
    cur.execute(s) 

das Ergebnis der 2 Drucke sind dies:

insert into MY_TABLE values(10, 'Készítés') 
<type 'unicode'> 

Wie Sie die Art der s sehen kann Unicode ist, aber trotzdem habe ich diese Fehlermeldung:

UnicodeEncodeError: 'ascii' codec can't encode character u'\xe9' in position 54: ordinal not in range(128) 

Ich habe mit und ohne u „“ versucht, mit und ohne Codierung und Decodierung auf alle möglichen Weisen, aber immer noch die gleiche Fehlermeldung

Jede Idee?

+0

Sie ein * kodieren * Fehlermeldung erhalten, weil 'cur.execute()' Bytestring erwartet. –

+0

Ja, aber mein erster Versuch war das: cur.execute ("Einfügen in MYTABLE-Werte (% s,% s)", (int (df.iloc [i] ['kkod']), df.iloc [i] ['kkodnev'])) – Gabor

Antwort

1

Sie geben eine Unicode-SQL-Anweisung an cursor.execute(). Diese Methode kann nur eine bytestring SQL-Anweisung.

Sie sollten die Zeichenfolgeninterpolation nicht verwenden, um Ihre Unicode-Werte in die SQL-Abfrage einzufügen (die wiederum nur ASCII ist). Verwenden Sie Abfrageparameter immer!

s = "insert into MY_TABLE values(:0, :1)" 
cur.execute(s, (int(df.iloc[i]['kkod']), df.iloc[i]['kkodnev'])) 

die Werte Nun wird als Parameter eingeführt übergeben, und es ist bis zu dem Datenbank-Adapter zur Codierung dieser correcty (wie auch richtig zu entkommen die Werte SQL-Injection-Probleme zu umgehen) zu kümmern.

Die oben genannten Verwendungen (Positions) Argumente nummeriert, können Sie auch Parameter verwenden genannt, mit passenden Schlüssel in den Werten in einem Wörterbuch übergeben:

s = "insert into MY_TABLE values(:kkod, :kkodnev)" 
cur.execute(s, {'kkod': int(df.iloc[i]['kkod']), 'kkodnev': df.iloc[i]['kkodnev']}) 

Sie müssen sicher sowohl Ihre Verbindung und Ihr Tisch machen Spalte ist korrekt konfiguriert, um Unicode zu behandeln. Zum Beispiel werden Sie die NLS_LANG Option gesetzt haben:

import os 
os.environ['NLS_LANG'] = '.AL32UTF8' 
+0

Funktioniert immer noch nicht. Ich habe das: s = "in MYTABLE Werte einfügen (: kkod,: kkodnev)" Druckart (en) ist: und die exec: cur.execute (s, {'kkod': int (df.iloc [i] ['kkod']), 'kkodnev': df.iloc [i] ['kkodnev']}), aber die gleiche Fehlermeldung: UnicodeEncodeError: 'ascii' Codec kann das Zeichen u '\ xe9' in Position 11 nicht codieren : Ordnungszahl nicht im Bereich (128) – Gabor

+0

@Gabor: Stellen Sie als erstes 100% sicher, dass das Traceback die 'cursor.execute()' Zeile enthält. Vielleicht verschieben Sie die Definition des Parameterwörterbuchs in eine separate Zeile ('params = {'kkod': int (df.iloc [i] ['kkod']), 'kkodnev': df.iloc [i] ['kkodnev']} ',' cur.execute (s, params) '), und vergewissern Sie sich, dass der Traceback immer noch den Aufruf cur.execute()' beschuldigt. Stellen Sie dann sicher, dass Ihre Datenbankspalte vom richtigen Typ zum Speichern von Unicode ist, z. 'NVARCHAR2'. Was ist 'NLS_LANG' für dich eingestellt? –

+0

Traceback (letzter Aufruf zuletzt): Datei "oracle_insert.py", Zeile 15, in cur.execute (s, {'kkod': int (df.iloc [i] ['kkod']), ' kkodnev ': df.iloc [i] [' kkodnev ']}) UnicodeEncodeError:' ascii 'Codec kann das Zeichen u' \ xe9 'nicht an Position 11 codieren: Ordnungszahl nicht im Bereich (128) – Gabor