Vorgehen um Zeichensatz-Probleme zu vermeiden?

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Dookie
Python-Forum Veteran
Beiträge: 2010
Registriert: Freitag 11. Oktober 2002, 18:00
Wohnort: Salzburg
Kontaktdaten:

Stimmt ich verwende VIM, bei VIM kannst du auch das "fileencoding" einstellen bzw. automatisch für verschiedene Sourcetypen einstellen lassen.
Auch Unicode wird sehr gut unterstützt bei VIM.

Mein Beispiel hab ich in der IPython-Console gemacht, geht in einer normalen Pythonconsole genauso.


Gruß

Dookie
[code]#!/usr/bin/env python
import this[/code]
Clython
User
Beiträge: 151
Registriert: Samstag 21. August 2004, 13:58
Wohnort: Schweiz, BE-2500

Mal unabhängig davon, ob mein Editor die Files korrekt anzeigt, hat sich ein neues Problem aufgetan, dessen Ursache (und Lösung) mir nach stundenlangen Recherchen im Netz nicht klar wurde:

Ich habe also diese UTF-8 Files. Wenn ich deren Inhalt in eine mySQL Datenbank einlesen will, kriege ich folgende Fehlermeldung:

Code: Alles auswählen

(Heizen/Kühlen)

Traceback (most recent call last):
  File "sql_processes.py", line 54, in ?
    sql_fill_wortliste()
  File "sql_processes.py", line 29, in sql_fill_wortliste
    sql_write_word(wort, ID, cursor)
  File "sql_processes.py", line 8, in sql_write_word
    output = cursor.execute("""insert into wortliste_d (id, wort, x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, vorkommen) values (%s, '%s', %s, %s, %s
, %s, %s, %s, %s, %s, %s, %s, '%s')""" % (ID, word, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, foo))
  File "d:\python23\lib\site-packages\MySQLdb\cursors.py", line 95, in execute
    return self._execute(query, args)
  File "d:\python23\lib\site-packages\MySQLdb\cursors.py", line 114, in _execute
    self.errorhandler(self, exc, value)
  File "d:\python23\lib\site-packages\MySQLdb\connections.py", line 33, in defaulterrorhandler
    raise errorclass, errorvalue
UnicodeEncodeError: 'ascii' codec can't encode character u'\xfc' in position 107: ordinal not in range(128)
Man muss dabei noch anmerken, dass zum Beispiel das Zeichen ü in emacs als ü angezeigt wird. Das gleiche gilt für alle anderen Umlaute und das Grad (°) Zeichen.

Ändere ich ü in ü usw. (das dann auch in WordpadMFC und emacs so angezeigt wird, wenn ich die Datei abspeichere und neu öffne, erzeugt das Script folgende Fehlermeldung:

Code: Alles auswählen

Traceback (most recent call last):
  File "sql_processes.py", line 54, in ?
    sql_fill_wortliste()
  File "sql_processes.py", line 31, in sql_fill_wortliste
    wort = infile.readline()
  File "d:\python23\lib\codecs.py", line 384, in readline
    return self.reader.readline(size)
  File "d:\python23\lib\codecs.py", line 295, in readline
    return self.decode(line, self.errors)[0]
UnicodeDecodeError: 'utf8' codec can't decode bytes in position 9-14: unsupported Unicode code range 
Wo liegt das Problem? In der Datenbank (die übrigens unter UTF-8 läuft) oder Python. Wie kann ich das Problem beheben?

Quelltext:

Code: Alles auswählen

def sql_write_word(word, ID, cursor):
    foo = "leer"
    output = cursor.execute("""insert into wortliste_d (id, wort, x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, vorkommen) values (%s, '%s', %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, '%s')""" % (ID, word, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, foo))
    print output

def sql_fill_wortliste():
    print "Bitte geben Sie Datei an:"
    infile_name = raw_input()
    infile = codecs.open(infile_name, "r", "utf-8")
    ID = 1
    print ID
    wort = infile.readline()
    conn = MySQLdb.connect(db="niklaus", user="mael")
    cursor = conn.cursor()
    while wort:
        sql_write_word(wort, ID, cursor)
        ID = ID + 1
        wort = infile.readline()
        print ID
        print wort
    print "Ende"
    conn.close()
    infile.close()
Dookie
Python-Forum Veteran
Beiträge: 2010
Registriert: Freitag 11. Oktober 2002, 18:00
Wohnort: Salzburg
Kontaktdaten:

Die Datei enthälst im 2. Fall kein UTF-8.

änder mal die Zeile 8 so daß du an den cursor einen Unicodestring übergibst.

Code: Alles auswählen

output = cursor.execute(u"""insert into wortliste_d (id, wort, x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, vorkommen) values (%s, '%s', %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, '%s')""" % (ID, word, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, foo))

Gruß

Dookie
[code]#!/usr/bin/env python
import this[/code]
Patrick
User
Beiträge: 49
Registriert: Montag 5. Juli 2004, 06:35
Wohnort: Berlin
Kontaktdaten:

Bei mir funktioniert das alles nicht.
Ich kann die von einem HTML-Formular empfangenen Strings codieren und decodieren wie ich will, mit welchem Zeichensatz ich will oder was auch immer.
Sobald ich den String in die MySQL-Datenbank schreiben will, heisst es:
UnicodeDecodeError: 'ascii' codec can't decode byte 0xf6 in position 0: ordinal not in range(128)
:-(
Benutzeravatar
gerold
Python-Forum Veteran
Beiträge: 5555
Registriert: Samstag 28. Februar 2004, 22:04
Wohnort: Oberhofen im Inntal (Tirol)
Kontaktdaten:

Patrick hat geschrieben: Sobald ich den String in die MySQL-Datenbank schreiben will, heisst es:
UnicodeDecodeError: 'ascii' codec can't decode byte 0xf6 in position 0: ordinal not in range(128)
Hi Patrick!

Füttere deine Datenbank mit Unicode-Strings. Ob deine Datenbankschnittstelle mit Unicode-Strings arbeitet, das lässt sich sehr einfach herausfinden. Lass dir von der Datenbank ein Feld, das mit Text befüllt ist, zurück geben und prüfe die Variable, in die du den Wert gespeichert hast. type(variablename) --> gibt dir den Objekttype zurück. Wenn dann Unicode raus kommt, dann bekommst du von der Datenbank Unicode-Strings und sollst diese auch mit korrekten Unicode-Strings füttern.

Siehe auch http://www.python-forum.de/viewtopic.php?t=5095

mfg
Gerold
:-)
http://halvar.at | Kleiner Bascom AVR Kurs
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
Patrick
User
Beiträge: 49
Registriert: Montag 5. Juli 2004, 06:35
Wohnort: Berlin
Kontaktdaten:

Hallo gerold,

danke fuer deine Antwort.
Ja, deine Anleitung habe ich auch schon gelesen, hat mich aber leider nicht weiter gebracht.
Vom Verstaendnis her schon, aber funktionieren tut es damit immer noch nicht.

Was ich von der Datenbank zurueck bekomme ist ein String, mehr gibt es nicht zu lesen.

Code: Alles auswählen

dbIf.execute('SELECT email,startguthaben FROM reseller WHERE id = '+rueck[0]+';')
reseller = dbIf.fetchone()
print type(reseller[0])
Ergebnis:
<type 'str'>
Danke,
Patrick
Patrick
User
Beiträge: 49
Registriert: Montag 5. Juli 2004, 06:35
Wohnort: Berlin
Kontaktdaten:

Laut Servervariablen laeuft der MySQL uebrigens mit latin1:
character set latin1
Antworten