Seite 1 von 1

Django: You must not use 8-bit bytestrings...

Verfasst: Dienstag 9. August 2011, 17:08
von ready
Hallo,

ich habe ein Problem in Django. Ich habe ein Script geschrieben welches mir in Django Daten aus SQL Tabellen in Models einträgt. Das Script funktionierte bisher gut, nun habe ich es um eine Tabelle/Model erweitert. Beim speichern des Models bekomme ich nun eine eigenartige Fehlermeldung mit der ich nichts anfangen kann. Ich habe danach gegooglet. Man findet ein paar Treffer aber nichts wirklich hilfreiches. Da der Fehler beim speichern des Models auftritt vermute ich dass es an Django da das speichern ein Bestandteil davon ist.
Wer kennt die Fehlermeldung oder kann damit was anfangen und möchte mir helfen? Bin um jede Hilfe dankbar! Hier nun die Fehlermeldung:

Code: Alles auswählen

Traceback (most recent call last):
  File "dbsync.py", line 1024, in <module>
    init_mmv()
  File "dbsync.py", line 978, in init_mmv
    add_rows(d)
  File "dbsync.py", line 906, in add_rows
    e.save()
  File "/usr/local/lib/python2.6/dist-packages/django/db/models/base.py", line 460, in save
    self.save_base(using=using, force_insert=force_insert, force_update=force_update)
  File "/usr/local/lib/python2.6/dist-packages/django/db/models/base.py", line 553, in save_base
    result = manager._insert(values, return_id=update_pk, using=using)
  File "/usr/local/lib/python2.6/dist-packages/django/db/models/manager.py", line 195, in _insert
    return insert_query(self.model, values, **kwargs)
  File "/usr/local/lib/python2.6/dist-packages/django/db/models/query.py", line 1436, in insert_query
    return query.get_compiler(using=using).execute_sql(return_id)
  File "/usr/local/lib/python2.6/dist-packages/django/db/models/sql/compiler.py", line 791, in execute_sql
    cursor = super(SQLInsertCompiler, self).execute_sql(None)
  File "/usr/local/lib/python2.6/dist-packages/django/db/models/sql/compiler.py", line 735, in execute_sql
    cursor.execute(sql, params)
  File "/usr/local/lib/python2.6/dist-packages/django/db/backends/util.py", line 34, in execute
    return self.cursor.execute(sql, params)
  File "/usr/local/lib/python2.6/dist-packages/django/db/backends/sqlite3/base.py", line 234, in execute
    return Database.Cursor.execute(self, query, params)
django.db.utils.DatabaseError: You must not use 8-bit bytestrings unless you use a text_factory that can interpret 8-bit bytestrings (like text_factory = str). It is highly recommended that you instead just switch your application to Unicode strings.

Re: Django: You must not use 8-bit bytestrings...

Verfasst: Dienstag 9. August 2011, 17:45
von Hyperion
Das übliche Problem mit Byte- vs. Unicode-Strings. Zum Verständnis der Thematik verweise ich auf meine Signatur :-)

Vermutlich arbeitest Du an einer Stelle intern nicht mit Unicode, sondern benutzt Bytestrings. Schau Dir halt mal die betreffende Stelle im Code an. Irgend wo hast Du da unsauber gearbeitet.

Re: Django: You must not use 8-bit bytestrings...

Verfasst: Dienstag 16. August 2011, 10:46
von ready
Hallo,

habe mir eine funktion geschrieben, die den Fehler behebt. Die funktion lasse ich einfach auf jedes Feld im Model laufen, dass ich in die Datenbank einfügen will. Schon kommt keine Fehlermeldung mehr.. mfg ready

Code: Alles auswählen

def fixunicodes(txt):
  if type(txt) is not str:
    return txt
  
  replace = {"\xf6": "ö",
             "\xd6": "Ö",
             "\xe4": "ä",
             "\xc4": "Ä",
             "\xfc": "ü",
             "\xdc": "Ü",
             "\xdf": "ß",
             "\xb0": "°",
             "\xb2": "²" }
  
  for k in replace.keys():
    txt = string.replace(txt,k,replace[k])
    
  return txt

Re: Django: You must not use 8-bit bytestrings...

Verfasst: Dienstag 16. August 2011, 10:58
von jens
Das ist keine gute Lösung.

Lies dir mal http://wiki.python-forum.de/Von%20Umlau ... 0Encodings durch!

Wo kommen deine Daten die du in der DB Eintragen willst her? Du mußt sie einfach nach unicode wandeln und gut.

Re: Django: You must not use 8-bit bytestrings...

Verfasst: Dienstag 16. August 2011, 11:10
von ready
jens hat geschrieben:Das ist keine gute Lösung.

Lies dir mal http://wiki.python-forum.de/Von%20Umlau ... 0Encodings durch!
Habe ich schon 2 mal gelesen. Alles versucht was darin steht. Die funktionen .encode und .decode gibt es bei mir überhauptnicht. Was es gibt ist die funktion unicode(). Damit habe ich versucht die bytestrings umzuwandeln. Leider vergebens. Ein utf-8 encoding verwende ich bereits.
jens hat geschrieben:Wo kommen deine Daten die du in der DB Eintragen willst her? Du mußt sie einfach nach unicode wandeln und gut.
Kommt aus einer Postgres Datenbank.. die verwendet afaik ISO-8859-15 als encoding. Einfach umwandeln (mit unicode()) hilft nicht.

mfg ready

Re: Django: You must not use 8-bit bytestrings...

Verfasst: Dienstag 16. August 2011, 11:15
von jens
Greifst du auf die DB per Django ORM zu? Dann solltest du IMHO unicode bekommen. Ansonsten stimmt da was nicht.

Re: Django: You must not use 8-bit bytestrings...

Verfasst: Dienstag 16. August 2011, 11:19
von ready
jens hat geschrieben:Greifst du auf die DB per Django ORM zu?
Nein, sondern per psycopg2.
mfg ready

Re: Django: You must not use 8-bit bytestrings...

Verfasst: Dienstag 16. August 2011, 11:23
von jens
Jo, dann hast du das Problem schon mal eingekreist... Vielleicht baust du die Verbindung nicht richtig auf. Ich kenne mich allerdings mit Postgres nicht aus. Bei MySQLdb gibt es allerdings ein paar parameter die man setzten muß, damit man unicode erhält.

z.B. hab ich eben in https://code.djangoproject.com/browser/ ... g2/base.py das gefunden:

Code: Alles auswählen

psycopg2.extensions.register_type(psycopg2.extensions.UNICODE)
...
self.connection.set_client_encoding('UTF8')
Btw. warum nutzt du das ORM nicht?

Re: Django: You must not use 8-bit bytestrings...

Verfasst: Dienstag 16. August 2011, 13:25
von Hyperion
ready hat geschrieben:
jens hat geschrieben:Das ist keine gute Lösung.

Lies dir mal http://wiki.python-forum.de/Von%20Umlau ... 0Encodings durch!
Habe ich schon 2 mal gelesen. Alles versucht was darin steht. Die funktionen .encode und .decode gibt es bei mir überhauptnicht. Was es gibt ist die funktion unicode(). Damit habe ich versucht die bytestrings umzuwandeln. Leider vergebens.
Das sind auch Methoden von String-Objekten - das hättest Du beim Durcharbeiten des Links schon kapieren können... ich verweise auch gerne noch mal auf meine Signatur :D

Vermutlich befindet sich die Ursache tatsächlich bei der Verbindung zur Datenbank. Da kannst Du sicher das Encoding des in der DB verwendeten Encodings einstellen, damit der ORM von Django die korrekte Wandlung in Unicode durchführen kann.

Re: Django: You must not use 8-bit bytestrings...

Verfasst: Dienstag 16. August 2011, 13:45
von ready
jens hat geschrieben:Jo, dann hast du das Problem schon mal eingekreist... Vielleicht baust du die Verbindung nicht richtig auf. Ich kenne mich allerdings mit Postgres nicht aus. Bei MySQLdb gibt es allerdings ein paar parameter die man setzten muß, damit man unicode erhält.

z.B. hab ich eben in https://code.djangoproject.com/browser/ ... g2/base.py das gefunden:

Code: Alles auswählen

psycopg2.extensions.register_type(psycopg2.extensions.UNICODE)
...
self.connection.set_client_encoding('UTF8')
Super, mit den Funktionen geht es jetzt auch ohne die o.g. fixunicodes Funktion.
jens hat geschrieben:Btw. warum nutzt du das ORM nicht?
Weil die Tabellen, die ich da auslese ja auch nicht mit dem ORM erzeugt wurden, sondern schon in Postgres existieren. Außerdem gab es damals glaub ich noch nicht die Möglichkeit in django mehrere Datenbanken zu verwenden. Jedenfalls bot sich das damals einfach nicht an =)

mfg ready

Re: Django: You must not use 8-bit bytestrings...

Verfasst: Dienstag 16. August 2011, 13:59
von ready
Hyperion hat geschrieben: Das sind auch Methoden von String-Objekten
Das hab ich schon geschnallt. Nur meine String Objekte scheinen diese Methode nicht zu haben. Verwende Python 2.6.
mfg ready

Re: Django: You must not use 8-bit bytestrings...

Verfasst: Dienstag 16. August 2011, 14:01
von Hyperion
ready hat geschrieben:
Hyperion hat geschrieben: Das sind auch Methoden von String-Objekten
Das hab ich schon geschnallt. Nur meine String Objekte scheinen diese Methode nicht zu haben. Verwende Python 2.6.
mfg ready
Das kann nicht sein! Entweder sind es keine Strings oder aber Du interpretierst das "nicht haben" falsch.

Re: Django: You must not use 8-bit bytestrings...

Verfasst: Dienstag 16. August 2011, 14:24
von jens
ready hat geschrieben:
jens hat geschrieben:Btw. warum nutzt du das ORM nicht?
Weil die Tabellen, die ich da auslese ja auch nicht mit dem ORM erzeugt wurden, sondern schon in Postgres existieren. Außerdem gab es damals glaub ich noch nicht die Möglichkeit in django mehrere Datenbanken zu verwenden. Jedenfalls bot sich das damals einfach nicht an =)
Du kennst aber inspectdb oder? -> https://docs.djangoproject.com/en/1.3/r ... #inspectdb

Re: Django: You must not use 8-bit bytestrings...

Verfasst: Dienstag 16. August 2011, 16:04
von ready
jens hat geschrieben:Du kennst aber inspectdb oder? -> https://docs.djangoproject.com/en/1.3/r ... #inspectdb
Kannte ich noch nicht, danke für den Hinweis.