Hallo,
ich hab ein Problem mit folgendem Szenario:
Ich habe eine Mysql DB die laut phmyadmin mit utf8_unicode kodiert ist.
Dort stehen Umlauten in der Form "Müller" drin.
Das Python Skript läuft auf einem Linux System und soll jetzt ne Abfrage, etwa nach Namen durchführen und das Ergebnis in eine Datei schreiben.
Hierbei hätte ich gerne, die Umlaute zu ü ä ö in der resultierenden Datei selbst umgewandelt.
So jetzt hab ich folgendes Problem, zum einen funktioniert die Abfrage nicht. Wenn ich mir den SQL Befehl mit dem die Abfrage durchgeführt wird, auf der Konsole ausgeben lasse steht da dran Nachname="Müller", also in der Form in der es auch in der DB steht und trotzdem krieg ich nur ein leeres Ergebnis zurück und nicht den entsprechenden Datensatz.
Zudem hab ich es nicht hingebracht, dass Python in den Dateien auch wirklich die Umlaute reinschreibt.
Ausprobiert hab ich schon alles mögliche, sprich im Skript oben z.B. # -*- coding: utf-8 -*- anzugeben, oder auch latin-1 oder iso-8859-1. Und alle möglichen Kombinationen von decode und encode mit den drei Kodierungen.
Ich dachte eigentlich, wenn das mit utf-8 in der DB steht, geb ich in meinem Skript coding: latin-1 an, wende decode('utf_8) auf die entsprechenden Felder an und hab dann meine Umlaute, aber das wirft nur Fehler...
Weiß jemand wie das mit den Umlauten in Python richtig funktioniert, ich bin mit meinem latein (haha) am Ende D:
Umlaut Problem
@Dreiven: In dem Kodierungskommentar am Anfang einer Quelltextdatei muss die Kodierung stehen, die im Quelltext auch tatsächlich verwendet wird. Und die gilt auch nur für literale Unicode-Zeichenketten. Da muss der Compiler ja wissen wie er die Bytes in der Quelltextdatei als Zeichen interpretieren muss.
Wenn Du sagst in der Datenbank stehen die Daten als "Müller" oder es wird Dir Auf der Konsole `Nachname="Müller"` ausgegeben, sagt uns das überhaupt nichts. Zu so einer Ausgabe gehört immer die Information welche Kodierung das Ausgabemedium erwartet hat. Sonst ist das nicht eindeutig. Besser ist es wenn Du die Bytewerte angibst oder bei Zeichenketten (`str`) die `repr()`-Form. Denn nur so weiss man woraus die Daten *tatsächlich* bestehen.
Wenn Du sagst in der Datenbank stehen die Daten als "Müller" oder es wird Dir Auf der Konsole `Nachname="Müller"` ausgegeben, sagt uns das überhaupt nichts. Zu so einer Ausgabe gehört immer die Information welche Kodierung das Ausgabemedium erwartet hat. Sonst ist das nicht eindeutig. Besser ist es wenn Du die Bytewerte angibst oder bei Zeichenketten (`str`) die `repr()`-Form. Denn nur so weiss man woraus die Daten *tatsächlich* bestehen.
@Dreiven: Dann solltest Du grundsätzlich mit Unicode-Objekten arbeiten. Das sollte man sowieso tun, wenn man mit Text arbeitet.
- noisefloor
- User
- Beiträge: 3856
- Registriert: Mittwoch 17. Oktober 2007, 21:40
- Wohnort: WW
- Kontaktdaten:
Hallo,
was bei mir mal Probleme bereite hat war ein falsches "Transfer-Encoding", welches in der config-Datei von MySQL stand.
Wenn du z.B. alles in UTF-8 hast, dass Transfer-Encoding aber auf "latin-1" steht, kann das solche Fehler verursachen.
Gruß, noisefloor
was bei mir mal Probleme bereite hat war ein falsches "Transfer-Encoding", welches in der config-Datei von MySQL stand.
Wenn du z.B. alles in UTF-8 hast, dass Transfer-Encoding aber auf "latin-1" steht, kann das solche Fehler verursachen.
Gruß, noisefloor
@noisefloor: Das 'ü' aus der Datenbank kommt doch anscheinend korrekt als Unicode-Objekt zurück.
- noisefloor
- User
- Beiträge: 3856
- Registriert: Mittwoch 17. Oktober 2007, 21:40
- Wohnort: WW
- Kontaktdaten:
Hallo,
es ist zwar schon länger her bei mir, aber die Transfer-Encoding - die es sowohl fürs Schreiben als auch fürs Lesen gibt - haben bei mir obskure Fehler (= falsche Zeichen) verursacht...
Da ich die Einstellungen der DB seinerzeit nicht ändern konnte, musste ich für das Schreiben alles nach Latin-1 wandeln, damit beim Lesen UTF-8 (ohne weiteres Zutun) rauskam. Wenn ich dass noch richtig im Kopf habe...
Wobei ich nicht sagen will, dass das hier auch der Fehler ist - aber man sollte das mal prüfen.
Besser ist natürlich, wie BlackJack schon sagte, vorm dem Schreiben noch Unicode zu dekodieren und dann nach dem Lesen nach UTF-8 (oder was auch immer zu Encodieren.
Gruß, noisefloor
es ist zwar schon länger her bei mir, aber die Transfer-Encoding - die es sowohl fürs Schreiben als auch fürs Lesen gibt - haben bei mir obskure Fehler (= falsche Zeichen) verursacht...
Da ich die Einstellungen der DB seinerzeit nicht ändern konnte, musste ich für das Schreiben alles nach Latin-1 wandeln, damit beim Lesen UTF-8 (ohne weiteres Zutun) rauskam. Wenn ich dass noch richtig im Kopf habe...
Wobei ich nicht sagen will, dass das hier auch der Fehler ist - aber man sollte das mal prüfen.
Besser ist natürlich, wie BlackJack schon sagte, vorm dem Schreiben noch Unicode zu dekodieren und dann nach dem Lesen nach UTF-8 (oder was auch immer zu Encodieren.
Gruß, noisefloor
Also versteh ich das richtig, ich soll direkt nach dem Lesen die Strings via .encode('gewünschte kodierung des strings') umwandeln und vor dem schreiben decode('unicode') drauf anwenden?
Ansonsten versteh ich nicht ganz was mit
Hab zwar gegoogled und einige Artikel zu Python/Umlauten/Unicode gelesen, aber so wirklich verstanden hab ich das ganze nicht~~
Ansonsten versteh ich nicht ganz was mit
gemeint ist.@Dreiven: Dann solltest Du grundsätzlich mit Unicode-Objekten arbeiten. Das sollte man sowieso tun, wenn man mit Text arbeitet.
Hab zwar gegoogled und einige Artikel zu Python/Umlauten/Unicode gelesen, aber so wirklich verstanden hab ich das ganze nicht~~
@Dreiven: Du bekommst von der Datenbank ja anscheinend schon Unicode-Objekte. In Deiner Anfrage, also wahrscheinlich in Deinem Skript stehen aber `str`-"Zeichenketten". Die müssten halt auch Unicode-Objekte sein.
Mit der Kombination von, .encode('utf-8') nach dem Auslesen und .decode("latin-1") vor dem befehl absenden , funktioniert das auslesen jetzt und ich krieg ein korrektes Ergebnis zurück.
Meine nächste Frage wäre jetzt, wie ich das Ergebniss kodieren muss, damit es nach schreiben in eine Datei die Umlaute als öäü darstellt.
.encode('latin-1') auf das Ergebnis funktioniert natürlich nicht...
Meine nächste Frage wäre jetzt, wie ich das Ergebniss kodieren muss, damit es nach schreiben in eine Datei die Umlaute als öäü darstellt.
.encode('latin-1') auf das Ergebnis funktioniert natürlich nicht...
@Dreiven: Das kommt darauf an in welcher Kodierung die Programme die den Text weiterverarbeiten ihn erwarten. Natürlich funktioniert auch 'latin-1' wenn man das haben möchte.
Wobei das mit den unsymmetrischen Kodierungen nicht gut klingt. Wenn das funktioniert ist etwas mit den DB-Einstellungen oder den Daten nicht okay.
Wobei das mit den unsymmetrischen Kodierungen nicht gut klingt. Wenn das funktioniert ist etwas mit den DB-Einstellungen oder den Daten nicht okay.
Damit wollte ich sagen, dass bei einem .encode('latin-1') versuch Fehler auftretenBlackJack hat geschrieben:@Dreiven: Das kommt darauf an in welcher Kodierung die Programme die den Text weiterverarbeiten ihn erwarten. Natürlich funktioniert auch 'latin-1' wenn man das haben möchte.
Ja, ich finds auch sehr merkwürdig und schwer nachvollziehbar.Wobei das mit den unsymmetrischen Kodierungen nicht gut klingt. Wenn das funktioniert ist etwas mit den DB-Einstellungen oder den Daten nicht okay.
Könnte das hierran liegen?
Aus den "MySQL-System-Variablen"Servervariablen und -einstellungen
character set client utf8
(Globaler Wert) latin1
character set connection utf8
(Globaler Wert) latin1
character set results utf8
(Globaler Wert) latin1
collation connection utf8_unicode_ci
(Globaler Wert) latin1_swedish_ci
Wobei ich am Server eh nix ändern darf.
- noisefloor
- User
- Beiträge: 3856
- Registriert: Mittwoch 17. Oktober 2007, 21:40
- Wohnort: WW
- Kontaktdaten:
Hallo,
@Dreiven: Man kann mit dem SQL-Befehl "set" diese Parameter überschreiben, ohne die Grundkonfig der DB anzupacken. Musst nur schauen, ob deine Benutzerrechte das hergeben...
Gruß, noisefloor
Genau das meinte ich mit den Transfer-Encodings. So musste ich das bei mir auch lösen, weil ich an der config von MySQL nichts ändern konnte. Warum MySQL per Voreinstellung (bzw. bei mir Ubuntu-Standardinstallation) latin und utf-8 mischt habe ich nie verstanden...Wenn das funktioniert ist etwas mit den DB-Einstellungen oder den Daten nicht okay.
@Dreiven: Man kann mit dem SQL-Befehl "set" diese Parameter überschreiben, ohne die Grundkonfig der DB anzupacken. Musst nur schauen, ob deine Benutzerrechte das hergeben...
Gruß, noisefloor
Danke für den Tipp^^noisefloor hat geschrieben: @Dreiven: Man kann mit dem SQL-Befehl "set" diese Parameter überschreiben, ohne die Grundkonfig der DB anzupacken. Musst nur schauen, ob deine Benutzerrechte das hergeben..
Habs zwar nicht so gelöst, aber das hat mich auf die Lösung gebracht!
Ich kann ja bei MySQLdb.connect() charset und use_unicode einstellen. Bisher war als charset utf8 (das was ja eigentlich die db hat) und use_unicode=True eingestellt.
Jetzt hab ich das ganze auf latin1 und False gestellt und siehe da schon funktionierts und die Umlaute werden korrekt dargestellt!
Und das alles komplett ohne ein einziges .decode/.encode im Code
- Hyperion
- Moderator
- Beiträge: 7478
- Registriert: Freitag 4. August 2006, 14:56
- Wohnort: Hamburg
- Kontaktdaten:
Der server seitige Wert war doch laut Auszug eh schon latin-1. Mich würde nun noch interessieren, ob Du im Script nun Byte-Strings oder Unicode-Strings erhältst!
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
assert encoding_kapiert