Umlaute Firebird etc

Installation und Anwendung von Datenbankschnittstellen wie SQLite, PostgreSQL, MariaDB/MySQL, der DB-API 2.0 und sonstigen Datenbanksystemen.
Antworten
pPilger
User
Beiträge: 45
Registriert: Montag 8. Februar 2010, 17:30

Hallo,

ich beginne gerade etwas in Python zu machen und habe mich mit den Umlauten ein wenig festgefahren:

Ich hole Datensätze aus einer Firebird-DB und möchte diese Daten in wieder in eine andere Tabellen schreiben.
Dabei bekomme ich z.B. diesen Fehler:
UnicodeEncodeError: 'ascii' codec can't encode character u'\xc4' in position 16: ordinal not in range(128)

Die Tabellen der db sind mit dem Zeichensatz WIN1252, also cp1252 angelegt.
Wenn ich die abgefragten Feldwerte im script prüfe, erhalte ich den typ unicode.
In meinen rückgabewerten steht da auch immer ein u davor: u'Mein Wert mit \xc4' (Mein Wet mit Ä)

Jetzt möchte ich diesen string einfach wieder in eine andere Tabelle bringen und bekomme obigen Fehler, wenn ich das ganze vor dem Insert so umwandle: c_title = b_title.encode("cp1252").

Wo liegt da mein Fehler?

Das python script habei c so auf diesen Zeichensatz gestellt:
# -*- coding: iso-8859-1 -*-

Programmierung und Test läuft unter linux ubuntu.

Danke für die Hilfe,
Jörg
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

Sagst du dem DB-Modul vor dem Auslesen denn, in welchem Encoding die Daten vorliegen? Ich vermute mal, dass die Umkodierung von der DB in Unicode schief laufen könnte...
BlackJack

@pPilger: Du bekommst von der DB *unicode*-Objekte, warum *gibst* Du ihr denn nicht auch welche!?
pPilger
User
Beiträge: 45
Registriert: Montag 8. Februar 2010, 17:30

BlackJack hat geschrieben:@pPilger: Du bekommst von der DB *unicode*-Objekte, warum *gibst* Du ihr denn nicht auch welche!?
Weil Pyton dann den umgekehrten ascii-Decode-Fehler wirft...
pPilger
User
Beiträge: 45
Registriert: Montag 8. Februar 2010, 17:30

Hyperion hat geschrieben:Sagst du dem DB-Modul vor dem Auslesen denn, in welchem Encoding die Daten vorliegen? Ich vermute mal, dass die Umkodierung von der DB in Unicode schief laufen könnte...
Wie mach ich das richtig?
ich benutze ganz normal z.B. fetchone()
was zurückgegeben wird ist dann z.B.
'1234',u'mein string mit codierten umlauten'
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

pPilger hat geschrieben: Wie mach ich das richtig?
k.A. wir hatten das hier neulich mal mit dem MySQLdb-Modul. Da gabs so ne art setEncoding() Funktion iirc.
ich benutze ganz normal z.B. fetchone()
was zurückgegeben wird ist dann z.B.
'1234',u'mein string mit codierten umlauten'
Nee, Das teilt man dem DB-Modul idR beim Verbindungsaufbau mit, also vor dem Absetzen von Queries.

Aber ich denke BlackJack hat da schon recht. Du solltest der DB auf jeden Fall wieder Unicode-Objekte übergeben. Teste es doch einfach mal erst, *ohne* vorher Daten aus einer DB zu holen, sondern schreib Unicode Daten aus dem Quellcode in die DB.
pPilger
User
Beiträge: 45
Registriert: Montag 8. Februar 2010, 17:30

Aber ich denke BlackJack hat da schon recht. Du solltest der DB auf jeden Fall wieder Unicode-Objekte übergeben. Teste es doch einfach mal erst, *ohne* vorher Daten aus einer DB zu holen, sondern schreib Unicode Daten aus dem Quellcode in die DB.
Also ich hab jetzt folgendes überprüft.
Der Feldinhalt den ich aus der db hole, ohne irgendwelche connection-settings wegen des zeichensatzes zu machen, kommt in python so an:
<type 'unicode'>

Wenn ich das auch ohne connection settings weiterreiche bekomme ich folgenden fehler:
'ascii' codec can't encode character u'\xc4'

Das ist das "Ä", welches er nicht verträgt.

Wandle ich den Feldinhalt vor dem insert so um, wie er in der db gespeichert werden müsste:
s = s.encode('cp1252')

bekomme ich folgenden Fehler:
UnicodeDecodeError: 'ascii' codec can't decode byte 0xc4

Das versteh ich noch nicht.
Auch wenn ich ein "Ä" aus dem script an die db schicke ist es das Gleiche.
Danke für die Hilfe!
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

pPilger hat geschrieben: Wenn ich das auch ohne connection settings weiterreiche bekomme ich folgenden fehler:
'ascii' codec can't encode character u'\xc4'
Und wenn Du mal aus dem Quellcode ein "Ä" ohne "connection setting" als Unicode-String an die DB übergibst?

Lies doch mal in der API-Doku nach, was wie verlangt wird...
pPilger
User
Beiträge: 45
Registriert: Montag 8. Februar 2010, 17:30

Hyperion hat geschrieben: Und wenn Du mal aus dem Quellcode ein "Ä" ohne "connection setting" als Unicode-String an die DB übergibst?
Also du meinst so: u'\xc4' ?
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

pPilger hat geschrieben:
Hyperion hat geschrieben: Und wenn Du mal aus dem Quellcode ein "Ä" ohne "connection setting" als Unicode-String an die DB übergibst?
Also du meinst so: u'\xc4' ?
Nein, ich meine

Code: Alles auswählen

u"ä"
Natürlich muss das Encoding der Script-Datei Umlaute unterstützen (also z.B. utf-8) und korrekt angegeben und auch exakt in dem encoding gespeichert sein.
pPilger
User
Beiträge: 45
Registriert: Montag 8. Februar 2010, 17:30

Danke für Deine Geduld:
Nein, ich meine

Code: Alles auswählen

u"ä"
Natürlich muss das Encoding der Script-Datei Umlaute unterstützen (also z.B. utf-8) und korrekt angegeben und auch exakt in dem encoding gespeichert sein.
Dann erhalte ich folgende Meldung:
'ascii' codec can't encode character u'\xc4' in position 128: ordinal not in range(128)

das script ist auf utf-8 eingestellt.
Ich vermute der Fehler kommt von Python und nicht von kinterbas!? Oder lieg' ich da falsch.
Grüße
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

pPilger hat geschrieben: Dann erhalte ich folgende Meldung:
'ascii' codec can't encode character u'\xc4' in position 128: ordinal not in range(128)
Das bringt uns doch schon mal weiter. Irgend wo will jetzt (vermutlich das Modul zur Datenbank) jemand den Unicode-String in einen Byte-String umwandeln (was prinzipiell ja auch so sein muss). Dafür will die Funktion aber ASCII verwenden, was ja nun einmal keine Umlaute usw. kennt. Du musst also irgend wie das Encoding der DB umstellen, da ASCII wohl augenscheinlich der Default ist.

Was uns zurück zur Dokumentation des Moduls bringt...
pPilger
User
Beiträge: 45
Registriert: Montag 8. Februar 2010, 17:30

Hyperion hat geschrieben:
pPilger hat geschrieben: Dann erhalte ich folgende Meldung:
'ascii' codec can't encode character u'\xc4' in position 128: ordinal not in range(128)
Was uns zurück zur Dokumentation des Moduls bringt...
OK, ich gebe jetzt beim db_connect das Char_Set mit an und kann nun auch Umlaute speichern.

Folgendes Problem habe ich aber noch.
Hole ich Daten z.B. mit diesem Wort aus der db:"Äther"
Dann wird bei meiner kontrollausgabe mit print eine eins drangehängt:
Äther 1
Die wandert auch mit in die DB. Woher kommt die und wie krieg ich sie wieder los?
In den "Rohdaten" sieht das so aus: u'\xc4ther 1'

Grüße
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

pPilger hat geschrieben: Hole ich Daten z.B. mit diesem Wort aus der db:"Äther"
Dann wird bei meiner kontrollausgabe mit print eine eins drangehängt:
Äther 1
Ist das nur bei Umlauten? Steht die "1" wirklich nicht schon in der DB drin?
Ohne Code-Beispiel geht hier gar nichts.
pPilger
User
Beiträge: 45
Registriert: Montag 8. Februar 2010, 17:30

Hyperion hat geschrieben:
pPilger hat geschrieben: Ist das nur bei Umlauten? Steht die "1" wirklich nicht schon in der DB drin?
Sorry, der Wald vor lauter Bäumen..-))

Den nächsten hatte ich hier:
x = x.replace("Ä", "&Auml;")

Aber jetzt weis ich ja, dass ich u"Ä" notieren muss.

Nochmals vielen Dank!!
Antworten