hallo allerseits,
bin python-beginner. habe gerade ein script geschrieben welches sich simple zu eine Oracle DB verbindet, eine
SQL abfrage tätigt und das ergebnis anschließend in eine CSV schreibt. klappt alles wunderbar bis auf diesen fehler (darum schreibt er die spalte auch nicht ins CSV):
"UnicodeEncodeError: 'ascii' codec can't encode character u'\xf6' in position 43: ordinal not in range(128)"
habe mich jetzt schon einige stunden mit Decode und Encode beschäftigt, mit UTF und was weiss ich was, aber nicht wirklich eine lösung gefunden wie er mir die abfrage vervollständigt...
hier das skript, vielleicht kann mir jemand als einsteiger ein paar tipps geben:
import cx_Oracle, csv
connection = cx_Oracle.connect("usr/pw@server/instance")
cursor = connection.cursor()
cursor.execute("SELECT foo FROM bar")
writer = csv.writer(open("file.csv","wb"))
writer.writerow(["eins","zwei","drei"])
writer.writerows(cursor)
cursor.close()
connection.close()
wäre für jeden tipp dankbar, vielen herzlichen dank
achja: python 2.5 / oracle 11g
infos zu DB:
NLS_CHARACTERSET = AL16UTF16
NLS_LANGUAGE = GERMAN
UnicodeEncodeError
-
deets
Bitte setzt deinen Code in python-tags, damit man ihn lesen kann. Zweitens poste bitte *mindestens* die Zeile, in welcher der Fehler passiert, natuerlich in Bezug auf das gepostete Snippet.
Ansonsten wuerde ich mal vermuten, dass du unicode Objekte von deinem Adapter bekommst, und versuchst die in eine Datei zu schreiben. Das geht natuerlich nicht ohne explizites encoding. Eine Moeglichkeit waere, aus dem Modul codecs einen writer fuer UTF-8 zu holen, und dass ungefaehr sowas zu machen:
Ansonsten wuerde ich mal vermuten, dass du unicode Objekte von deinem Adapter bekommst, und versuchst die in eine Datei zu schreiben. Das geht natuerlich nicht ohne explizites encoding. Eine Moeglichkeit waere, aus dem Modul codecs einen writer fuer UTF-8 zu holen, und dass ungefaehr sowas zu machen:
Code: Alles auswählen
import codecs
outf = codecs.writer("utf-8")(open("file.csv", "wb"))
writer = csv.writer(outf)
...
hallo, danke für die antwort und entschuldigung für meinen unleserlichen code
Traceback (most recent call last):
File "C:\abfrage.py", line 21, in <module>
writer.writerows(cursor)
UnicodeEncodeError: 'ascii' codec can't encode character u'\xf6' in position 43: ordinal not in range(128)
hab mal mit python 3.2 getestet, da kommt die fehlermeldung nicht, allerdings schreib er mir auch nichts in meine CSV;)
wenn ichs im interpreter reingebe bekomme ich eh alle ergenisse...logischerweise als "\xf6" und nicht als "ö"...
wie baue ich am besten deine möglichkeit ein?
danke nochmal und sorry für die unannehmlichkeiten
Code: Alles auswählen
import cx_Oracle, csv
connection = cx_Oracle.connect("usr/pw@server/instance")
cursor = connection.cursor()
cursor.execute("SELECT foo FROM bar")
writer = csv.writer(open("file.csv","wb"))
writer.writerow(["eins","zwei","drei"])
writer.writerows(cursor)
cursor.close()
connection.close()File "C:\abfrage.py", line 21, in <module>
writer.writerows(cursor)
UnicodeEncodeError: 'ascii' codec can't encode character u'\xf6' in position 43: ordinal not in range(128)
hab mal mit python 3.2 getestet, da kommt die fehlermeldung nicht, allerdings schreib er mir auch nichts in meine CSV;)
wenn ichs im interpreter reingebe bekomme ich eh alle ergenisse...logischerweise als "\xf6" und nicht als "ö"...
wie baue ich am besten deine möglichkeit ein?
danke nochmal und sorry für die unannehmlichkeiten
-
deets
Na, genau so wie ich sie geschrieben habe, das ersetzt dir doch exakt deine Code wie du den CSV-writer baust. Und du hast auch immer noch nicht erzaehlt, in welcher Zeile genau der Fehler passiert.
ja sorry, wie gesagt, hab bis vorgestern noch nicht viel ahnung von python gehabt...insofern bitte ich um rücksichtnahmen was das alles angeht...
wenn ich den code dann so ändere
dann gibts den fehler:
Traceback (most recent call last):
File "C:/abfrage", line 13, in <module>
outf = codecs.writer("utf-8")(open("C:/file.csv","w"))
AttributeError: 'module' object has no attribute 'writer'
und wo bitte schau ich nach in welcher zeile mein fehler passiert?? ja sorry, lacht mich aus, aber kein meister ist vom himmel gefallen...
ich lass das skript im interpreter laufen, da zeigt er mir nur den geposteten fehler an(soweit ich das seh)...
ich bedanke mich nochmals
wenn ich den code dann so ändere
Code: Alles auswählen
import codecs, cx_Oracle, csv
connection = cx_Oracle.connect("usr/pw@server/instance")
cursor = connection.cursor()
cursor.execute("SELECT foo FROM bar")
outf = codecs.writer("utf-8")(open("file.csv", "wb"))
writer = csv.writer(outf)
writer.writerows(cursor)
cursor.close()
connection.close()
Traceback (most recent call last):
File "C:/abfrage", line 13, in <module>
outf = codecs.writer("utf-8")(open("C:/file.csv","w"))
AttributeError: 'module' object has no attribute 'writer'
und wo bitte schau ich nach in welcher zeile mein fehler passiert?? ja sorry, lacht mich aus, aber kein meister ist vom himmel gefallen...
ich lass das skript im interpreter laufen, da zeigt er mir nur den geposteten fehler an(soweit ich das seh)...
ich bedanke mich nochmals
Wo der Fehler passiert ist steht in der Fehlermeldung: line 13.enrico83 hat geschrieben:Traceback (most recent call last):
File "C:/abfrage", line 13, in <module>
outf = codecs.writer("utf-8")(open("C:/file.csv","w"))
AttributeError: 'module' object has no attribute 'writer'
und wo bitte schau ich nach in welcher zeile mein fehler passiert?? ja sorry, lacht mich aus, aber kein meister ist vom himmel gefallen...
Verwende mal codecs.getwriter statt codecs.writer.
wenn ich es so mache:
kommt das selbe:
Traceback (most recent call last):
File "C:/Python32/test3_2.py", line 6, in <module>
writer = csv.getwriter(outf)
AttributeError: 'module' object has no attribute 'getwriter'
hab das ganze mit version 3.2.1 durchgeführt! mit 2.5 gibt er mir immer noch den alten fehler "
(UnicodeEncodeError: 'ascii' codec can't encode character u'\xf6' in position 43: ordinal not in range(128))
oder hab ich das modul falsch eingefügt im code? bzw. wenn ich nur
mit
ersetz gibts das
Traceback (most recent call last):
File "C:/Python32/test3_2.py", line 7, in <module>
writer.writerows(cursor)
File "C:\Python32\lib\codecs.py", line 356, in write
self.stream.write(data)
TypeError: must be str, not bytes
sorry, aber ich muss mir die syntax erst eingewöhnen
gibts weitere ideen
?
Code: Alles auswählen
import codecs, cx_Oracle, csv
connection = cx_Oracle.connect("us/pw@server")
cursor = connection.cursor()
cursor.execute("SELECT foo FROM bar")
outf = codecs.getwriter("utf-8")(open("C:/file.csv", "w"))
writer = csv.getwriter(outf)
writer.writerows(cursor)
cursor.close()
connection.close()Traceback (most recent call last):
File "C:/Python32/test3_2.py", line 6, in <module>
writer = csv.getwriter(outf)
AttributeError: 'module' object has no attribute 'getwriter'
hab das ganze mit version 3.2.1 durchgeführt! mit 2.5 gibt er mir immer noch den alten fehler "
(UnicodeEncodeError: 'ascii' codec can't encode character u'\xf6' in position 43: ordinal not in range(128))
oder hab ich das modul falsch eingefügt im code? bzw. wenn ich nur
Code: Alles auswählen
outf = codecs.writer("utf-8")(open("C:/file.csv", "w"))Code: Alles auswählen
outf = codecs.getwriter("utf-8")(open("C:/file.csv", "w"))Traceback (most recent call last):
File "C:/Python32/test3_2.py", line 7, in <module>
writer.writerows(cursor)
File "C:\Python32\lib\codecs.py", line 356, in write
self.stream.write(data)
TypeError: must be str, not bytes
sorry, aber ich muss mir die syntax erst eingewöhnen
gibts weitere ideen
-
deets
Gib doch mal bitte aus, was eigentilch aus der Datenbank rauskommt. Das modul pprint hilft dir dabei. Und zeige uns das.
also als ergebnis erhalte ich in meiner csv alle records ohne umlaute:
503799,Name Name,None,2984 02
810287,Name Name,None,2984 02
379748,Name Name,None,2984 02
640938,Name Name,None,2984 02
581775,Name Name,None,2984 02
id, name (eben manche mit umlaute), firmeninterne nummer..das wärs eigentlich
mittlerweile sieht der code so aus:
error:
aber ich steh an...
es kann von mir auch ein excel-sheet sein, solang das mit den umlauten bzw. encodierung klappt
503799,Name Name,None,2984 02
810287,Name Name,None,2984 02
379748,Name Name,None,2984 02
640938,Name Name,None,2984 02
581775,Name Name,None,2984 02
id, name (eben manche mit umlaute), firmeninterne nummer..das wärs eigentlich
mittlerweile sieht der code so aus:
Code: Alles auswählen
import codecs, cx_Oracle, csv
connection = cx_Oracle.connect("usr/pw@server/instance")
cursor = connection.cursor()
cursor.execute("SELECT foo From bar)
outf = codecs.open("C:/result.csv", "wb", encoding="utf-8")
writer = csv.writer(outf)
writer.writerows([[f.encode("utf-8") if type(f) is unicode else str(f) for f in r] for r in cursor])
cursor.close()
connection.close()Code: Alles auswählen
Traceback (most recent call last):
File "C:\abfrage.py", line 7, in <module>
writer.writerows([[f.encode("utf-8") if type(f) is unicode else str(f) for f in r] for r in cursor])
File "C:\PROGRA~1\Python25\Lib\codecs.py", line 638, in write
return self.writer.write(data)
File "C:\PROGRA~1\Python25\Lib\codecs.py", line 303, in write
data, consumed = self.encode(object, self.errors)
UnicodeDecodeError: 'ascii' codec can't decode byte 0xc3 in position 50: ordinal not in range(128)aber ich steh an...
es kann von mir auch ein excel-sheet sein, solang das mit den umlauten bzw. encodierung klappt
-
deets
Das ist nicht das, worum ich gebeten hatte. Ich moechte wirklich die genau repraesentation sehen, eine Ausgabe der Datenstrukturen mittels pprint. Und natuerlich auch und gerade dann, wenn Umlaute in den Daten sind!
Ausserdem bitte entweder entscheiden oder immer dazu angeben, welche Version von Python du benutzt (es waren ja 2.5 und 3.2 im Spiel), denn das ist gerade in diesem Bereich ein himmelweiter Unterschied und muss darum klar sein.
Ausserdem bitte entweder entscheiden oder immer dazu angeben, welche Version von Python du benutzt (es waren ja 2.5 und 3.2 im Spiel), denn das ist gerade in diesem Bereich ein himmelweiter Unterschied und muss darum klar sein.
bin und bleibe bei python 2.5.1...
ok danke..ich muss mich dann auch mal in das pprint einlesen um dir das gewünschte zu liefern...ich hoffe das dauert nicht allzulange
im interpreter erscheinen ja alle ergebnisse mit print (halt nicht codiert als umlaute)
ok danke..ich muss mich dann auch mal in das pprint einlesen um dir das gewünschte zu liefern...ich hoffe das dauert nicht allzulange
im interpreter erscheinen ja alle ergebnisse mit print (halt nicht codiert als umlaute)
-
deets
Ok, nochmal fuer die Oeffentlichkeit: die Datenbank liefert tatsaechlich unicode-Objekte zurueck, als Liste von Tupeln. So etwa:
Was dann noch fehlt ist die Angabe mit welcher Python-Version du diese Ausgabe produziert hast.
Code: Alles auswählen
[
(1111111,
u'\xf6',
None,
'irgendwas'),
]
-
deets
Ok, ich hab' jetzt nicht mehr Zeit dafuer, aber das hier geht. Das absurde ist, dass das outf mittels codecs.open genau so funktioniert, wie man es sich erwartet - aber in dem Moment, in dem man damit versucht mit dem CSV-Wrtier zu arbeiten, geht's in die Hose. Ich habe nicht den Hauch einer Ahnung warum, vielleicht erhellt uns wer anderes.
Code: Alles auswählen
import codecs, csv, pprint
outf = codecs.open("/tmp/result.csv", "w", encoding="utf-8")
outf.write(u'\xf6\n')
outf.close()
# und nochmal binaer und ohne transparentes encoding
outf = open("/tmp/result.csv", "ab")
writer = csv.writer(outf)
rows = [
(1111111,
u'\xf6',
None,
'irgendwas'),
]
pprint.pprint(rows)
encoded_rows = []
for row in rows:
encoded_rows.append(tuple(item.encode("utf-8") if isinstance(item, unicode) else item for item in row))
writer.writerows(encoded_rows)
ja ich danke mal vielmals für die hilfe..vielleicht hat hier jemand die glorreiche idee wie ich die daten in mein csv bekomm oder wo der fehler liegt...aber wie gesagt es muss ja nicht das unbedingt das csv modul sein, vielleicht ginge es ja mit excel...
-
deets
Erm, dir ist schon klar, dass mein code oben fuer dich einfach anzupassen ist, oder? Ich habe halt keine oracle datenbank (dankenswerterweise), geschweige denn deine Daten. Ein bisschen Eigenleistung musst du schon erbringen, und den Code einbauen....
-
BlackJack
@deets: Der CSV-Writer will halt kein `unicode` haben. Dem muss man `str` geben. Und damit braucht man dann kein `codecs.open()` mehr. Denn das will `unicode`, der CSV-Writer gibt aber `str` an das `file`-like weiter.
-
deets
@BlackJack: soweit, klar. Was mich wundert ist eben dieses beharren darauf. Was kuemmert's ihn? Einen Grund in technischer Hinsicht kann ich nicht sehen. Aber ist dann halt nen Implementationsartefakt.
