Sqlite und Umlaute (utf-8 --> Unicode --> iso-8859-1)

Installation und Anwendung von Datenbankschnittstellen wie SQLite, PostgreSQL, MariaDB/MySQL, der DB-API 2.0 und sonstigen Datenbanksystemen.
Antworten
mintpc
User
Beiträge: 50
Registriert: Montag 23. Januar 2012, 12:44

Hallo zusammen,

das Thema SQlite scheint ja ein Fass ohne Boden zu sein. Nachdem mein Datenbankprogrämmchen schön läuft (als
CGI-Script auf meinem Webspace, mit guter Unterstützung aus diesem Forum), bekomme ich plötzlich eine Fehlermeldung beim Eintrag von Umlauten.

Das Problem habe ich so gelöst, dass von iso 8859-1 in Unicode und dann in utf-8 umgewandelt wird:

Code: Alles auswählen

Nachricht = Nachricht.decode("iso-8859-1")
Nachricht = Nachricht.encode("utf-8")
Das funktioniert so wohl ganz gut!

Beim Auslesen aus der Datenbank hab ich den umgekehrten Weg versucht, der allerdings nicht klappt:

Code: Alles auswählen

Nachr = Nachr.decode("utf-8") 
Nachr = Nachricht.encode("iso-8859-1")
Es liefert mir immer eine Fehlermeldung gemäß ASCII ??
<type 'exceptions.UnicodeEncodeError'>: 'ascii' codec can't encode character u'\xfc' in position 7: ordinal not in range(128)
Wie bekomme ich das Problem in den Griff?

Vielen Dank schonmal
mintpc
nomnom
User
Beiträge: 487
Registriert: Mittwoch 19. Mai 2010, 16:25

mintpc hat geschrieben:

Code: Alles auswählen

Nachr = Nachr.decode("utf-8") 
Nachr = Nachricht.encode("iso-8859-1")
Wie soll das auch funktionieren mit „Nachr“ und „Nachricht“?

Edit: Da du dich vermutlich nur vertippt hast, würde ich mal sagen: Das kann gar nicht gehen, weil Nachr.decode('utf-8') versucht, in ASCII umzuwandeln. Und bei ASCII sind nur Zeichen bis Wert 127 erlaubt. 'ä' entspricht in UTF-8 allerdings 195 und 164 (hoffentlich).
mintpc
User
Beiträge: 50
Registriert: Montag 23. Januar 2012, 12:44

nomnom hat geschrieben:Da du dich vermutlich nur vertippt hast
Ja, natürlich ein Tippfehler. Sorry. Ich sitz hier schon Stunden.
nomnom hat geschrieben: weil Nachr.decode('utf-8') versucht, in ASCII umzuwandeln.
Das klingt plausibel.
So wie ich die Beiträge auf den entsprechenden Seiten deute, muss ich die Werte aus der Datenbank von "utf-8" erst in "unicode" umwandeln und dann von "Unicode" in "iso-8859-1".

Wie wandel ich denn "utf-8" in "Unicode" um?

mintpc
nomnom
User
Beiträge: 487
Registriert: Mittwoch 19. Mai 2010, 16:25

So: :) (Aus Hyperions Signatur)
reduce(verstehen, map(lesen, (Von Umlauten, Unicode und Encodings, Folien zum Thema Unicode und Python)))
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

nomnom hat geschrieben:So: :) (Aus Hyperions Signatur)
reduce(verstehen, map(lesen, (Von Umlauten, Unicode und Encodings, Folien zum Thema Unicode und Python)))
Welch Ehre :-D Sie wird also doch vom ein oder anderem wahrgenommen ;-)
mintpc hat geschrieben: Wie wandel ich denn "utf-8" in "Unicode" um?

Code: Alles auswählen

"String in utf-8".decode("utf-8")
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
mintpc
User
Beiträge: 50
Registriert: Montag 23. Januar 2012, 12:44

nomnom hat geschrieben:So: :) (Aus Hyperions Signatur)
reduce(verstehen, map(lesen, (Von Umlauten, Unicode und Encodings, Folien zum Thema Unicode und Python)))
Genau von da hab ich meine Informationen gehabt.
Hyperion hat geschrieben: Code:
"String in utf-8".decode("utf-8")
Genau so hab ich das ja gemacht (ohne den Tippfehler von oben) und da gab es die Fehlermeldung, die ich oben zitiert habe.

Ich finde den Fehler immer noch nicht.
BlackJack

@mintpc: Eine Lösung für *was* genau suchst Du denn noch? Die Frage wie man UTF-8 kodierte Bytes in ISO-8859-1 kodierte Bytes umwandelt, ist geklärt. Die Antwort wussten wir also.
mintpc
User
Beiträge: 50
Registriert: Montag 23. Januar 2012, 12:44

Also ... ich wandle einen Umlaut "ü" in rtf-8 um und trage ihn in meine Datenbank SQLite ein.

Soweit, so gut. Beim Auslesen des "ü" tritt ein Fehler auf. 'nomnom' hat hier auch klassifiziert, dass offensichtlich der genannte Befehl "Nachricht".decode('utf-8') versucht, in ASCII umzuwandeln. Ein Lösung gab er aber auch nicht.
nomnom hat geschrieben:Das kann gar nicht gehen, weil Nachr.decode('utf-8') versucht, in ASCII umzuwandeln. Und bei ASCII sind nur Zeichen bis Wert 127 erlaubt. 'ä' entspricht in UTF-8 allerdings 195 und 164
Ich will aber gar nicht in ASCII umwandeln, sondern nur das in UTF-8 codierte Zeichen wieder aus der Datenbank rauskriegen und irgendwie anzeigen.

Das heißt, die mir angebotenen Lösungen werfen immer wieder einen Fehler, und zwar an der Stelle, wo aus der Datenbank gelesen wird. Dasselbe Problem wurde auch schon hier im Forum angefragt, eine wirkliche Lösung gab es dazu aber nie (oder für mich nicht verständlich).

Hier ist vielleicht nochmal die Fehlermeldung:

Code: Alles auswählen

<type 'exceptions.UnicodeEncodeError'>: 'ascii' codec can't encode character u'\xfc' in position 0: ordinal not in range(128) 
Danke
mintpc
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

Ein `decode(some_codecname)` wandelt niemals in ASCII um, sondern in Unicode! Daran kann es nicht liegen!

Poste uns doch mal ein minimales, lauffähges Beispiel, welches erst etwas in die DB schreibt und dann etwas aussliest und genau den Fehler produziert. Du kannst dafür ":memory:" bei der Erstellung einer Connection nutzen, damit wir keine Datei anlegen müssen.

Nur so kommen wir hier weiter.
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
BlackJack

@Hyperion: Stimmt nicht ganz:

Code: Alles auswählen

In [49]: s.decode('utf-8')
---------------------------------------------------------------------------
UnicodeEncodeError                        Traceback (most recent call last)

/home/bj/<ipython console> in <module>()

/usr/lib/python2.6/encodings/utf_8.pyc in decode(input, errors)
     14 
     15 def decode(input, errors='strict'):
---> 16     return codecs.utf_8_decode(input, errors, True)
     17 
     18 class IncrementalEncoder(codecs.IncrementalEncoder):

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

In [50]: s
Out[50]: u'H\xe4ll\xf6'
@mintpc: Du solltest vielleicht mal schauen ob Deine Problembeschreibung zu den tatsächlichen Datentypen passt, die Du vorliegen hast.
Benutzeravatar
noisefloor
User
Beiträge: 3856
Registriert: Mittwoch 17. Oktober 2007, 21:40
Wohnort: WW
Kontaktdaten:

Hallo,

@mintpc: Warum willst du die Strings den encodiert speichern? Speicher' doch als Unicode. Per Default liefert SQLite Daten als Unicode zurück, kann man aber auch anders einstellen (Link)

Bis du sicher, dass der Fehler aus der DB kommt und nicht "erst", wenn du Daten per HTML ausgibst?

Gruß, noisefloor
Antworten