Seite 1 von 1

Problem mit UTF8

Verfasst: Mittwoch 3. Juni 2009, 18:22
von Caldar
Ich komme mit den Sonderzeichen-Codierungen (UTF8) irgendwie nicht ganz zurecht.

In meiner MySQL-Datenbank habe ich die Sonderzeichen mit dem Zeichensatz UTF8 codiert, nur beim Auslesen (ich will die DB-Einträge mit Sonderzeichen, z.B das °-Zeichen als solches in meiner Anwendung anzeigen lassen) bekomme ich Probleme. WIe bekomme ich das hin?
Konkret siehr das so aus, dass eben dieses Grad-Zeichen (°) in meiner Anwendung als "\xb0"-Literal ausgegeben wird.
Wie bringe ich nun meiner GUI bei, das Literal eben als ° zurückzuinterpretieren bzw darzustellen?

Verfasst: Mittwoch 3. Juni 2009, 18:32
von cofi
Bei GUI nehm ich mal an, dass es sich um PyQt handelt.

Wichtig wäre zu wissen, als was der String den vorliegt, bzw was du mit ihm machst, nachdem du ihn von der Datenbank bekommen hast.

Falls du ihn als Bytestring von der DB bekommst, hilft dir ein `string.decode('utf8')` zu einem Unicode-Objekt, mit dem PyQt zurecht kommt.
Allerdings versagt dann auch schon meine Kristallkugel -> need input.

Verfasst: Mittwoch 3. Juni 2009, 18:39
von Caldar
Ich habs jetzt duch Ausprobieren folgendermaßen hinbekommen:

Code: Alles auswählen

 def tbaNames(self):

        sql = "SELECT name FROM nameslist"
        self.curs.execute(sql)
        TbaName = []
             
        for row in self.curs:
            x = "%s" % row
            tbaName.append(x)        
        return tbaName
Ich habe also den Result Set von der DB, der ja in self.curs vorliegt (die Cursor und Connection Obj u. dgl sind in Konstruktor verstaut).
Über diesen iteriere ich jetzt und mache etwas sehr unelegantes:
x = "%s" % row

Je nun, es hilft! :) Die Literale werden als Sonderzeichen interpretiert und in die tbaName geschrieben.
Aber ist so halt mit der Kirch ums Dorf.
Und ja, ich verwende PyQt und MySQL

Verfasst: Mittwoch 3. Juni 2009, 18:53
von cofi
Dann schau dir mal an was dein `x` denn überhaupt ist -> type(x)

Sag mal ist das ein Tippfehler oder springt dir da tatsächlich ein NameError entgegen? Wo ich grad schon bei den Namen bin: Sprechende Namen sind eine tolle Sache, man sollte sie nutzen ;)

Verfasst: Mittwoch 3. Juni 2009, 19:23
von Caldar
Der Typ von x ist String, is klar.

Aber wen ich folgendes mache:

Code: Alles auswählen

entry = str(row)
wird mein Tuple-Datentyp zwar ebenfalls auf einen String gecastet (heißt das in Python auch so?, ich kenns von Java), aber das Problem mit den fehlerhaften Sonderzeichen bleibt. Außerdem wird jedes Tuple mit (' blbla ') also mit Klammer und einfachem Anführungszeichen eingetütet.
Irgendwie komm ich da nicht mehr mit.

Verfasst: Mittwoch 3. Juni 2009, 19:59
von cofi
Dass es ein String ist, ist eben nicht klar, denn du willst für PyQt bzw. da du mit Unicode arbeitest eigentlich Unicodeobjekte und keine Bytestreams. daran kommst du indem du eben `.decode('utf8')` bei deinen Strings aufrufst.

Was ist dein `row` eigentlich ? Ein String? Oder nun doch ein Tupel? Gib mal bitte den Output von `repr(row)` bzw `type(row)` an.

Casten ist IMHO nicht gebräuchlich bei nicht statisch typisierten Sprachen, da der konkrete/formale Typ bei Duck-typing sowieso nebensächlich ist.

Verfasst: Mittwoch 3. Juni 2009, 20:37
von BlackJack
Auch in Java wäre das kein "cast"en, denn ``(String) irgendeinObjekt``, was ein "cast" wäre, ist etwas anderes als ``irgendeinObjekt.toString()``. Und von letzterem sprechen wir hier letztendlich in beiden Sprachen.

Verfasst: Donnerstag 4. Juni 2009, 12:17
von Caldar
cofi hat geschrieben: Was ist dein `row` eigentlich ? Ein String? Oder nun doch ein Tupel? Gib mal bitte den Output von `repr(row)` bzw `type(row)` an.
Also row ist ein Tuple:
type(row) bringt: <type 'tuple'>
repr(row) bringt den Inhalt des Datensatzes, also z.B.: ('Fehlerflag',)

Verfasst: Donnerstag 4. Juni 2009, 12:22
von Hyperion
Caldar hat geschrieben: Also row ist ein Tuple:
type(row) bringt: <type 'tuple'>
repr(row) bringt den Inhalt des Datensatzes, also z.B.: ('Fehlerflag',)
Wir brauchen aber den Typen der einzelnen Felder im Tupel, also z.B. row[0]. Denn da ist ja das eigentliche Problem!

Code: Alles auswählen

In [5]: t = (u"Hallöle", "Welt")

In [6]: repr(t)
Out[6]: "(u'Hall\\x94le', 'Welt')"

In [7]: type(t)
Out[7]: <type 'tuple'>

In [8]: type(t[0])
Out[8]: <type 'unicode'>

In [9]: type(t[1])
Out[9]: <type 'str'>

Verfasst: Donnerstag 4. Juni 2009, 12:25
von cofi
Naja wobei `repr` schon zeigt, dass es sich um einen String und nicht um ein Unicodeobjekt handelt.

Du solltest deine Funktion so abwandeln:

Code: Alles auswählen

def tbaNames(self):
	sql = "SELECT name FROM nameslist"
	self.curs.execute(sql)
	return [row[0].decode("utf8") for row in self.curs]

Verfasst: Donnerstag 4. Juni 2009, 12:31
von Caldar
Da bringt er mir einen:
UnicodeDecodeError: 'utf8' codec can't decode byte 0xb0 in position 19: unexpected code byte

D.h. es ist gar kein UTF8? Aber in MySQL habe ich als Kollation in der abzurufenden Tabelle 'utf8-bin' stehen?!

Verfasst: Donnerstag 4. Juni 2009, 12:41
von Hyperion
Caldar hat geschrieben:Da bringt er mir einen:
UnicodeDecodeError: 'utf8' codec can't decode byte 0xb0 in position 19: unexpected code byte

D.h. es ist gar kein UTF8? Aber in MySQL habe ich als Kollation in der abzurufenden Tabelle 'utf8-bin' stehen?!
Und der Character-set der Tabelle? Die Kollation hat ja afaik nur Bedeutung bei internen Vergelichsoperationen ...

Verfasst: Donnerstag 4. Juni 2009, 12:48
von Caldar
Den Character set habe ich gar nicht angegeben. Ich finde in phpmyadmin(nehme ich zur Verwaltung von MySQL) auch kein Feld, in dem ich das festlegen kann. Nur eben die Kollation. Aber ich probiere mal mit den Darstellungsumwandlungen rum...

Verfasst: Donnerstag 4. Juni 2009, 13:15
von Hyperion
Caldar hat geschrieben:Den Character set habe ich gar nicht angegeben.
Na dann wird das vermutlich die Standardeinstellung sein. Auf jeden Fall muss man den natürlich entsprechend einstellen.
Ich finde in phpmyadmin(nehme ich zur Verwaltung von MySQL) auch kein Feld, in dem ich das festlegen kann. Nur eben die Kollation.
Na, bin mir sicher, dass es da was geben muss ... ich gucke mal. Mach doch mal einen Dump. Da drin sollte bei einem kompletten dump stehen, welches Character-set genutzt wird!