^^ das war mir direkt nach dem Posten hier auch schon aufgefallen und hab es dannb gleich behoben ^^jens hat geschrieben: EDIT: @meneliel: Bei cursor.close fehlen die Klammern Ohne die wird nix gemacht...
Encoding-Problem
- jens
- Python-Forum Veteran
- Beiträge: 8502
- Registriert: Dienstag 10. August 2004, 09:40
- Wohnort: duisburg
- Kontaktdaten:
Vermutlich ist %s der falsche Platzhalter.
Aus http://www.python.org/dev/peps/pep-0249/ :
Aus http://www.python.org/dev/peps/pep-0249/ :
Mach mal ein print db.paramstyleparamstyle
String constant stating the type of parameter marker
formatting expected by the interface. Possible values are
[2]:
'qmark' Question mark style,
e.g. '...WHERE name=?'
'numeric' Numeric, positional style,
e.g. '...WHERE name=:1'
'named' Named style,
e.g. '...WHERE name=:name'
'format' ANSI C printf format codes,
e.g. '...WHERE name=%s'
'pyformat' Python extended format codes,
e.g. '...WHERE name=%(name)s'
Code: Alles auswählen
In [41]: print db.paramstyle
---------------------------------------------------------------------------
AttributeError Traceback (most recent call last)
C:\Dokumente und Einstellungen\mengel\Desktop\<ipython console>
AttributeError: 'cx_Oracle.Connection' object has no attribute 'paramstyle'
Die Frage ist: löst das denn mein Encoding Problem? Bisher konnte ich so jedefalls immer aus der DB lesen und in sie schreiben. Nur dass ich seit letzte WOche plötzlich Probleme mit den Umlauten habe.
Und wenn ich aus der DB lese, oder Werte ohne Variablen rein schreibe (z.B. INSERT INTO ADRESSEN (PfBezNr) VALUES('ö')) - seh ich immer noch keine Umlaute ....
- jens
- Python-Forum Veteran
- Beiträge: 8502
- Registriert: Dienstag 10. August 2004, 09:40
- Wohnort: duisburg
- Kontaktdaten:
google gefragt und das gefunden:
Also muß es so gehen:
Code: Alles auswählen
>>> import cx_Oracle
>>> cx_Oracle.paramstyle
'named'
Code: Alles auswählen
db = DB()
cursor = self.db.cursor()
cursor.execute(
"INSERT INTO ADRESSEN (PfBezNr) VALUES(:data)",
{ "data": u'\xe4' }
)
danke ...
... würde aber das Umschreiben von ca. 15 funktionierenden Scripten mit sich ziehen ... ist dann vielleicht sicher angebracht, aber löst aktuell das Problem nicht, welches ich dringend noch diese Woche lösen will/muss um nächste Woche mit beruhigt in meine Flitterwochen zu fahren ...^^
Davon abgesehen, dass ich kein Unicode an der Stelle verwenden kann führt ein
nicht zur Lösung und ich habe weiterhin Umlaute in der Datenbank.
PS: nach dem Execute hab ich natürlich auch ein commit gemacht (nur um der Frage vorzubeugen ...^^)
... würde aber das Umschreiben von ca. 15 funktionierenden Scripten mit sich ziehen ... ist dann vielleicht sicher angebracht, aber löst aktuell das Problem nicht, welches ich dringend noch diese Woche lösen will/muss um nächste Woche mit beruhigt in meine Flitterwochen zu fahren ...^^
Davon abgesehen, dass ich kein Unicode an der Stelle verwenden kann führt ein
Code: Alles auswählen
cursor.execute("INSERT INTO ADRESSEN (PfBEZNR) VALUES(:data)", {"data":u'\xe4'.encode("cp1252")})
PS: nach dem Execute hab ich natürlich auch ein commit gemacht (nur um der Frage vorzubeugen ...^^)
- jens
- Python-Forum Veteran
- Beiträge: 8502
- Registriert: Dienstag 10. August 2004, 09:40
- Wohnort: duisburg
- Kontaktdaten:
Dann ist wohl einfach "cp1252" falsch. Bei MySQL kann man auch explizit sagen, welches Encoding verwendet wird.
Schau dich mal hier um: http://www.google.de/search?hl=de&q=cx_ ... uche&meta=
Schau dich mal hier um: http://www.google.de/search?hl=de&q=cx_ ... uche&meta=
@meneliel: Kann es sein, dass die DB gar kein `str` liefert, sondern `cx_Oracle.STRING` und das die als `str()`/`repr()`-Darstellung aus einem 'ä' ein 'a' machen?
Hast Du der Vorschlag mit den Platzhaltern im SQL und direktes verfüttern von Unicode-Objekten an `execute()` eigentlich schon ausprobiert? Wenn Du Glück hast, kümmert sich das DB-Modul dann automatisch um die korrekte Kodierung.
Hast Du der Vorschlag mit den Platzhaltern im SQL und direktes verfüttern von Unicode-Objekten an `execute()` eigentlich schon ausprobiert? Wenn Du Glück hast, kümmert sich das DB-Modul dann automatisch um die korrekte Kodierung.
aber mein sqldeveloper sagt mir das das environment encoding cp1252 ist, mein DBA teilte mir gleiches mit, auf die Frage, wie das DB-Encoding ist.
Und ich hab ja jetzt auch schon probiert utf-8 oder iso-codierte Strings darein zuschreiben.
*aufgeb*
Und ich hab ja jetzt auch schon probiert utf-8 oder iso-codierte Strings darein zuschreiben.
*aufgeb*
k.A.BlackJack hat geschrieben:@meneliel: Kann es sein, dass die DB gar kein `str` liefert, sondern `cx_Oracle.STRING` und das die als `str()`/`repr()`-Darstellung aus einem 'ä' ein 'a' machen?
ja hab ich und ja auch schon geschrieben, dass das mit Unicode nicht geht.BlackJack hat geschrieben: Hast Du der Vorschlag mit den Platzhaltern im SQL und direktes verfüttern von Unicode-Objekten an `execute()` eigentlich schon ausprobiert? Wenn Du Glück hast, kümmert sich das DB-Modul dann automatisch um die korrekte Kodierung.
Code: Alles auswählen
In [49]: cursor.execute("INSERT INTO ADDRESSEN (PfBEZNR) VALUES(:data)", {"data":u'\xe4'})
---------------------------------------------------------------------------
NotSupportedError Traceback (most recent call last)
C:\Dokumente und Einstellungen\mengel\Desktop\<ipython console>
NotSupportedError: Variable_TypeByValue(): unhandled data type unicode
- jens
- Python-Forum Veteran
- Beiträge: 8502
- Registriert: Dienstag 10. August 2004, 09:40
- Wohnort: duisburg
- Kontaktdaten:
btw. bei MySQL kann man beim erstellen einer Datenbank auch ein encoding angeben. Ist das evtl. auch bei Oracle möglich?
Hast du dir aus meiner google suche die Seite http://osdir.com/ml/python.db.cx-oracle ... 00007.html angesehen? Da ist was mit select value from v$nls_parameters where parameter = 'NLS_CHARACTERSET'
Mit was siehst du denn, ob die Daten richtig sind oder nicht? Vielleicht zweigt dein Datenbank-anguck-programm die Daten einfach nur falsch an.
Vergleich das doch mal direkt in Python, ungefähr so:
TEST_STRING = u'\xe4'
insert mit TEST_STRING.encode("cp1252")
select des wertes, dann ein print select_result.decode("cp1252") == TEST_STRING
Hast du dir aus meiner google suche die Seite http://osdir.com/ml/python.db.cx-oracle ... 00007.html angesehen? Da ist was mit select value from v$nls_parameters where parameter = 'NLS_CHARACTERSET'
Mit was siehst du denn, ob die Daten richtig sind oder nicht? Vielleicht zweigt dein Datenbank-anguck-programm die Daten einfach nur falsch an.
Vergleich das doch mal direkt in Python, ungefähr so:
TEST_STRING = u'\xe4'
insert mit TEST_STRING.encode("cp1252")
select des wertes, dann ein print select_result.decode("cp1252") == TEST_STRING
Möglich? Ich lege ja keine Datenbank an. Die Datenbank selber liegt auch auf einem Server. Hab ich ein neues Projekt, gibt mir unser DBA entsprechend einen neuen Nutzer und Rechte zum Tabellen anlegen.jens hat geschrieben:btw. bei MySQL kann man beim erstellen einer Datenbank auch ein encoding angeben. Ist das evtl. auch bei Oracle möglich?
Hab ich angeguckt, weiß aber im Moment nicht wie mir das weiterhelfen kann und noch keine Zeit hatte da jetzt genauer zu gucken. Bin ja parallel dabei noch eine alternative Lösung zu finden, falls das jetzt alles nicht klappen sollte. Wie gesagt, ich muss bis Ende der Woche spätestens das Problem gelöst haben, eigentlich schon vor 2 Tagen.jens hat geschrieben: Hast du dir aus meiner google suche die Seite http://osdir.com/ml/python.db.cx-oracle ... 00007.html angesehen? Da ist was mit select value from v$nls_parameters where parameter = 'NLS_CHARACTERSET'
^^ meine Datenbank-Anguckprogramme: SQLDeveloper und ArcGIS 9.3 Catalog. Zeigen beide das identische an. Wie bereits auch schon mal geschrieben, hatte ich das ja auch schon vermutet, dass beide vielleicht identisch nur irgendwas anzeigen, was im Hintergrund anders gespeichert ist. Nur: das ArcGIS muss die Daten weiterverarbeiten können und muss in dem Fall Adressen suchen - hab das getestet. Zum Suchen wird der Anzeige-String benutzt, in dem Sonderzeichen stehen.jens hat geschrieben: Mit was siehst du denn, ob die Daten richtig sind oder nicht? Vielleicht zweigt dein Datenbank-anguck-programm die Daten einfach nur falsch an.
BTW: wenn ich die csv-Datei, die eigentlich eine xlxs ist über ArcCatalog importiere und da eine Datenbanktabelle draus mache, sind alle Umlaute korrekt. (.. mmhhhh.... den Umweg könnte ich immer noch gehen, meine Script-Ergebnisse in eine neue csv schreiben, die fix in Excel importieren und dann so importieren... aber das ist doof, weil ich wissen warum das alles nicht klappt )
Ergebnis:jens hat geschrieben: Vergleich das doch mal direkt in Python, ungefähr so:
TEST_STRING = u'\xe4'
insert mit TEST_STRING.encode("cp1252")
select des wertes, dann ein print select_result.decode("cp1252") == TEST_STRING
Code: Alles auswählen
print row[1].decode("cp1252")
print repr(row[1].decode("cp1252"))
print row[1].decode("cp1252") == test
# ausgeben in der MyEclipse Console:
?
u'?'
False
Habe mal kurz in die `cx_Oracle`-Dokumentation geschaut und gesehen, dass `Connection`-Objekte die Attribute `encoding` und `nencoding` haben. Was sagen die denn?
Und kann man Oracle vielleicht per "SQL" irgendwie sagen, welche Kodierung man gerne hätte?
Und kann man Oracle vielleicht per "SQL" irgendwie sagen, welche Kodierung man gerne hätte?
- jens
- Python-Forum Veteran
- Beiträge: 8502
- Registriert: Dienstag 10. August 2004, 09:40
- Wohnort: duisburg
- Kontaktdaten:
OK, dann kannst du also quasi nicht selber eine Datenbank anlegen und mußt das nehmen was da ist... Genau dann wird aber dieser Select Befehl mit NLS_CHARACTERSET interessant. Setzt den mal ab und schau nach was er zurück liefert.
Hab sowas mal für MySQLdb gemacht, siehe: http://www.python-forum.de/topic-8002.html
Der Sourcecode ist noch online: http://paste.pocoo.org/show/301/
Da es ein Fragezeichen ist, wurde irgendwann ein decode mit Fehlerbehandlung 'replace' gemacht (s. http://docs.python.org/dev/library/stdt ... str.decode ). Da du das nicht gemacht hast, hat es wohl der Datenbank Adapter getan. Ich gehe einfach davon aus, das cp1252 falsch ist. Du könntest eine Routine bauen, die einfach mal alle möglichen Codecs durchgeht und schau bei welchem es klappt. Irgendwie doof, aber vielleicht aufschlußreiche.meneliel hat geschrieben:Code: Alles auswählen
# ausgeben in der MyEclipse Console: ? u'?' False
Hab sowas mal für MySQLdb gemacht, siehe: http://www.python-forum.de/topic-8002.html
Der Sourcecode ist noch online: http://paste.pocoo.org/show/301/