subprocess und encoding...

Ich möchte per subprocess das Programm mysqldump benutzten. Das klappt Grundsätzlich schon, allerdings hab ich Probleme mit dem Encoding. Ich möchte die Ausgaben gern nach unicode wandeln. Ich hab gesehen das subprocess.PIPE (also process.stdout) ein encoding Attribut besitzt. Leider ist das aber == None ;( Ansonsten Probiere ich einfach ["ASCII", "latin1", "utf8"] durch. ASCII klappt natürlich immer dann, wenn keine Umlaute vorkommen. Aber sind welche enthalten klappt es auch mit latin1 und utf8 nicht. mysqldump hat den Parameter default-character-set: """ Use charset_name as the default character set. See Section 5.10.1, "The Character Set Used for Data and Sorting". If not specified, mysqldump from MySQL 4.1.2 or later uses utf8, and earlier versions use latin1. """ http://dev.mysql.com/doc/refman/4.1/en/mysqldump.html Egal ob ich default-character-set auf utf8 oder latin1 stelle, das wandeln in unicode klappt in Python nicht... Am Ende bleibt mir nicht's anderes übrig als aus Ausgaben mit errors="replace" in unicode zu wandeln, aber das Ergebniss hat dann natürlich statt Umlaute nur noch Fragezeichen :( Nun also zwei Fragen: -Was kann ich tun damit ein definierter Codec benutzt wird? -Kann ich die Ausgaben irgendwie als RAW-Daten in unicode bringen? Also eine Alternative zu errors="replace" ? -- Mfg. Jens Diemer ---- CMS in pure Python CGI: http://www.pylucid.org _______________________________________________ python-de maillist - python-de@python.net http://python.net/mailman/listinfo/python-de

On Monday 19 June 2006 09:29, Jens Diemer wrote:
Ich möchte per subprocess das Programm mysqldump benutzten. Das klappt Grundsätzlich schon, allerdings hab ich Probleme mit dem Encoding. Ich möchte die Ausgaben gern nach unicode wandeln.
Ich hab gesehen das subprocess.PIPE (also process.stdout) ein encoding Attribut besitzt. Leider ist das aber == None ;(
Ansonsten Probiere ich einfach ["ASCII", "latin1", "utf8"] durch. ASCII klappt natürlich immer dann, wenn keine Umlaute vorkommen. Aber sind welche enthalten klappt es auch mit latin1 und utf8 nicht.
Diie Reihenfolge ist unsinnig. du solltest zuerst utf8 und DANN latin1 probieren (wenn du schon probierst). Dann latin1 ist ein byte-encoding, und alles was du dem gibts schluckt es auch.
mysqldump hat den Parameter default-character-set: """ Use charset_name as the default character set. See Section 5.10.1, "The Character Set Used for Data and Sorting". If not specified, mysqldump from MySQL 4.1.2 or later uses utf8, and earlier versions use latin1. """ http://dev.mysql.com/doc/refman/4.1/en/mysqldump.html
Egal ob ich default-character-set auf utf8 oder latin1 stelle, das wandeln in unicode klappt in Python nicht...
Ohne das du uns Daten und/oder code zeigst kann man das nicht einschätzen.
Am Ende bleibt mir nicht's anderes übrig als aus Ausgaben mit errors="replace" in unicode zu wandeln, aber das Ergebniss hat dann natürlich statt Umlaute nur noch Fragezeichen :(
Nun also zwei Fragen: -Was kann ich tun damit ein definierter Codec benutzt wird?
Du kannst den stream wrappen mittes des codecs modules. Das klappt aber nur, wenn mysqldump korrekte Daten liefert.
-Kann ich die Ausgaben irgendwie als RAW-Daten in unicode bringen? Also eine Alternative zu errors="replace" ?
Natürlich nicht! Wenn es dir egal ist (so scheints ja), dann bleib doch einfach bei byte-strings. Da kannst du allen Ranz mit transportieren. Ich bin mir nicht sicher, wie mysql funtkioniert - aber es könnte sein, das du schon falsch codierte Daten in der datenbank hast. Wenn das der Fall ist, dann musst du eben probieren. Oder die Daten bereinigen. MfG Diez _______________________________________________ python-de maillist - python-de@python.net http://python.net/mailman/listinfo/python-de

Diez B. Roggisch schrieb:
Ansonsten Probiere ich einfach ["ASCII", "latin1", "utf8"] durch.
Ohne das du uns Daten und/oder code zeigst kann man das nicht einschätzen.
Gut das du das geschrieben hast... Ich hab nämlich den Code mal zusammen gefasst und ein paar Debug-Ausgaben eingebaut... Und es hat sich gezeigt, das durch einen dummen Schreibfehler gar nicht die Codecs durchprobiert wurden, sondern nur drei mal hintereinander mit ASCII getestet wurde :( Zu dumm... Nun klappt es mit utf8! Der Vollständigkeitshalber aber hier mal der Code: ============================================================================ #!/usr/bin/python # -*- coding: UTF-8 -*- print "Content-type: text/html; charset=utf-8\r\n\r\n" import cgitb;cgitb.enable() import sys, subprocess command = ( "mysqldump --default-character-set=utf8 --compact" " -uUserName -pPassword -hlocalhost DatabaseName" " --tables PyLucid_styles" ) work_dir = "/usr/bin" #~ command = "ls -al && echo TEST: äöüß" #~ work_dir = "." process = subprocess.Popen( command, cwd = work_dir, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, ) #~ process.wait() out_data = process.stdout.read() print "<pre>" print "process.stdout.encoding:", process.stdout.encoding encoding = sys.stdin.encoding or sys.getdefaultencoding() print "encoding:", encoding encodings = [encoding, "utf8", "latin1"] def make_unicode(encodings, out_data): print encodings for encoding in encodings: print "Test encoding:", encoding try: out_data = unicode(out_data, encoding, errors="strict") except UnicodeError, e: print "Fail:", e continue else: print "encoding OK:", encoding return out_data print "no encoding found!" return out_data out_data = make_unicode(encodings, out_data) print "-"*80 print out_data.encode("utf8") print "</pre>" ============================================================================ Ich frag mich nur, wie ich an "utf8" herankommen kann. Denn es sieht so aus: sys.stdin.encoding: None sys.stdout.encoding: None sys.stderr.encoding: None sys.getdefaultencoding(): ascii sys.getfilesystemencoding(): ANSI_X3.4-1968 locale.getlocale(): (None, None) locale.getdefaultlocale(): (None, None) locale.getpreferredencoding(): ANSI_X3.4-1968 Also nirgends brauchbare Daten... OK in meinem Fall kann ich utf8 aus dem mysqldump Programm-Parameter '--default-character-set=' ableiten. Aber so generell... Welches encoding nutzt subprocess??? Wobei... ...such... ...such... Das Problem hatte ich schonmal: http://python.net/pipermail/python-de/2006q2/thread.html#7661 Da ist wohl mein Linux nicht richtig eingestellt! Wobei es bei Alturo noch schlimmer aussieht: sys.stdin.encoding: Error: Object has no .encoding! sys.stdout.encoding: Error: Object has no .encoding! sys.stderr.encoding: Error: Object has no .encoding! sys.getdefaultencoding(): ascii sys.getfilesystemencoding(): Error: 'module' object has no attribute 'getfilesystemencoding' locale.getlocale(): (None, None) locale.getdefaultlocale(): (None, None) locale.getpreferredencoding(): Error: 'module' object has no attribute 'getpreferredencoding' Wobei da auch Python uralt ist: Python v2.2.1 (#1, Aug 25 2004, 16:56:05) [GCC 2.95.4 20011002 (Debian prerelease)] Naja, dann bleib ich einfach beim dummen Probieren... -- Mfg. Jens Diemer ---- CMS in pure Python CGI: http://www.pylucid.org _______________________________________________ python-de maillist - python-de@python.net http://python.net/mailman/listinfo/python-de

Ich frag mich nur, wie ich an "utf8" herankommen kann. Denn es sieht so aus:
sys.stdin.encoding: None sys.stdout.encoding: None sys.stderr.encoding: None sys.getdefaultencoding(): ascii sys.getfilesystemencoding(): ANSI_X3.4-1968 locale.getlocale(): (None, None) locale.getdefaultlocale(): (None, None) locale.getpreferredencoding(): ANSI_X3.4-1968
Also nirgends brauchbare Daten...
Das liegt daran, das die standard ein/ausgaben NIE ein encoding haben, genausowenig wie pipes zu subprozessen. Und das mit gutem Grund: was wenn du eine pipe zu einem PNG-generator aufbauen willst? Dann brauchst du byte-streams. Das ist der minimale Vertrag, den man mit einem subprozess shcliessen kann.
OK in meinem Fall kann ich utf8 aus dem mysqldump Programm-Parameter '--default-character-set=' ableiten. Aber so generell... Welches encoding nutzt subprocess???
Siehe oben: keines. Wenn dein konkreter Anwendungszweck es erlaubt, kannst du wie beschrieben die files in encoding-aware streams wrappen.
Naja, dann bleib ich einfach beim dummen Probieren...
Besser ist, den Problemen auf den Grund zu gehen. Wenn du vermurkste Daten in der DB hast, finde raus woher. MfG Diez _______________________________________________ python-de maillist - python-de@python.net http://python.net/mailman/listinfo/python-de

Diez B. Roggisch schrieb:
sys.stdin.encoding: None sys.stdout.encoding: None Das liegt daran, das die standard ein/ausgaben NIE ein encoding haben, genausowenig wie pipes zu subprozessen. Und das mit gutem Grund: was wenn du eine pipe zu einem PNG-generator aufbauen willst? Dann brauchst du byte-streams. Das ist der minimale Vertrag, den man mit einem subprozess shcliessen kann. Das stimmt nicht ganz. Zwar spuckt z.B. sys.stdout.encoding unter Windows nur None aus, unter Linux hab ich da aber UTF-8. Wäre auch irgendwie merkwürdig, das die Objekte überhaupt ein Attribut .encoding haben, wenn das keinen Sinn macht...
Naja, dann bleib ich einfach beim dummen Probieren... Besser ist, den Problemen auf den Grund zu gehen. Wenn du vermurkste Daten in der DB hast, finde raus woher.
Also in der DB hab ich auf jeden Fall die richtigen Daten. Ich versuche generell alles in UTF-8 zu speichern. In PyLucid selber, aber auch in phpMyAdmin sehe ich die Umlaute korrekt. Von daher gehe ich mal einfach davon aus, das sie auch korrekt in der DB gespeichert werden ;) Am liebsten wäre mich eigentlich ich könnte den Dump anders als mit dem Programm mysqldump erzeugen... Es gibt bei MySQL zwar das Statement: SHOW CREATE TABLE Aber ich hab nichts gefunden um die Zeilen-INSERT zu generieren. Wobei man das auch einfach selber erzeugen lassen kann... Naja, so wie es jetzt ist klappt es erstmal... Übrigends ist der eigentliche subprocess-Sourcecode noch ein wenig komplizierter, weil ich einen Timeout haben möchte. Die Sourcen sind hier zu finden: https://opensvn.csie.org/traccgi/PyLucid/browser/branches/0.7/PyLucid/system... -- Mfg. Jens Diemer ---- CMS in pure Python CGI: http://www.pylucid.org _______________________________________________ python-de maillist - python-de@python.net http://python.net/mailman/listinfo/python-de

Das stimmt nicht ganz. Zwar spuckt z.B. sys.stdout.encoding unter Windows nur None aus, unter Linux hab ich da aber UTF-8. Wäre auch irgendwie merkwürdig, das die Objekte überhaupt ein Attribut .encoding haben, wenn das keinen Sinn macht...
Aus der Doku: """ encoding The encoding that this file uses. When Unicode strings are written to a file, they will be converted to byte strings using this encoding. In addition, when the file is connected to a terminal, the attribute gives the encoding that the terminal is likely to use (that information might be incorrect if the user has misconfigured the terminal). The attribute is read-only and may not be present on all file-like objects. It may also be None, in which case the file uses the system default encoding for converting Unicode strings. New in version 2.3. """ Es ist also eher geraten. Aber zwischen Prozessen kennt unix kein encoding von pipes - das ist und bleibt deine Sache, auf beiden Seiten für korrekte en/dekodierung zu sorgen. Ich sehe in subprocess auch keinen Parameter, der das beeinflusst. Also bleibt es dabei: du musst die files wrappen.
Also in der DB hab ich auf jeden Fall die richtigen Daten. Ich versuche generell alles in UTF-8 zu speichern. In PyLucid selber, aber auch in phpMyAdmin sehe ich die Umlaute korrekt. Von daher gehe ich mal einfach davon aus, das sie auch korrekt in der DB gespeichert werden ;)
Dann verstehe ich nicht, warum du nicht alles in utf-8 dekodieren kannst. MfG Diez _______________________________________________ python-de maillist - python-de@python.net http://python.net/mailman/listinfo/python-de

Interessanter Ausschnitt aus der Doku ;) Diez B. Roggisch schrieb:
Also in der DB hab ich auf jeden Fall die richtigen Daten. Ich versuche generell alles in UTF-8 zu speichern. In PyLucid selber, aber auch in phpMyAdmin sehe ich die Umlaute korrekt. Von daher gehe ich mal einfach davon aus, das sie auch korrekt in der DB gespeichert werden ;)
Dann verstehe ich nicht, warum du nicht alles in utf-8 dekodieren kannst.
Doch das kann ich ja jetzt. Das hatte ich auch schon geschrieben ;) Zuerst sah es so aus als funktionierte kein Codec, aber daran war nur der Schreibfehler schuld ;) -- Mfg. Jens Diemer ---- CMS in pure Python CGI: http://www.pylucid.org _______________________________________________ python-de maillist - python-de@python.net http://python.net/mailman/listinfo/python-de
participants (2)
-
Diez B. Roggisch
-
Jens Diemer