Kodowanie UTF-8 w python (django, pylons, sqlalchemy, mako)

Pisanie aplikacji pythonowskich, dla początkujących wiąże się z problemami z kodowaniem. Jako, że już mam te początki za sobą w tym artykule postaram się omówić te problemy i podać rozwiązanie.

Mysql – założenia

Zanim przystąpimy do prac, musimy się upewnić, że nasza baza jest w kodowaniu utf-8. Ogólnie wszystko jest napisane w manualu [link]. Najbardziej powinien nas interesować punkt 9.1.4.[link]. A najbardziej zapytania do mysql, w których możemy się dowiedzieć o aktualnym kodowaniu,

SHOW VARIABLES LIKE ‘character_set%’;
SHOW VARIABLES LIKE ‘collation%’;

oraz polecenia zmieniające to kodowanie na utf-8

SET NAMES ‘utf8′;
SET CHARACTER SET utf8;

SET character_set_client = utf8;
SET character_set_results = utf8;
SET character_set_connection = utf8;
SET character_set_database = utf8;
SET character_set_server = utf8;

SET NAMES ‘utf8′ COLLATE ‘utf8_unicode_ci’;

charset utf8;

Wydaje mi się, że to powinno starczyć – ogólnie ja przyjąłem zasadę, że zmieniam wszystkie zmienne (które mogę wyciągnąć po przez dwa pierwsze polecenia) na utf8. Wtedy mam pewność, że wszystko co związane z tą bazą jest w UTF8, a co za tym idzie nie muszę o tym już nigdzie pamiętać.

Django

Zaczynam od najprostszego frameworka Django, on w sobie zawiera ORM do bazy danych, i domyślnie korzysta właśnie z niego. Abyśmy nie mieli problemów z kodowaniem w pliku settings.py należy umieścić kod:

DATABASE_OPTIONS = {’use_unicode’: True, ‘charset’: ‘utf8′}

Na ten temat można by pisać i pisać, np o tym, że Django korzysta z biblioteki MySQLdb, itp itd – ale tutaj skupiam się jedynie na tym, aby nasza aplikacja działała zgodnie z polskimi znaczkami :)

Pylons, sqlalchemy

Jako, że podstawowym orm dla pylonsa jest sqlalchemy, ten akapit dotyczy właśnie tego modułu.
Tutaj problem pojawia się podczas definiowania modeli, standardowo jest tak, że gdy chcemy aby w bazie była kolumna Varchar, w definicji sqlalchemy wpisujemy

Column(’name’, types.String(255)),

Jak się okazuje jest to za mało, bo taka deklaracja nie wystarcza nam w zupełności. Trzeba typ string zamienić na Unicode, czyli powyższy kod powinien wyglądać tak:

Columns(’name’, types.Unicode(255)),

Jeżeli chcemy mieć w tabeli pole typu text, blobtext itp, definiujemy to w ten sposób

Column(’value’, types.TEXT(convert_unicode=True)),

Czyli dodajemy “convert_unicode=True”

W sqlalchemy to powinno wystaczyć.

Mako

Tutaj mamy mniejszy problem z znalezieniem rozwiązania niż w poprzednich przypadkach – wystarczy wpisać w google “mako utf” – pierwszy wynik na stronie opisuje nam jak to wykonać.

Zakładamy, że korzystamy w frameworka pylons.

W pliku PROJECT_DIR/config/environment.py wstawiamy linijkę

tmpl_options['mako.input_encoding'] = ‘utf-8′

Więcej nie będę pisać na temat mako – zapraszam na stronę [link].

To by było na tyle z tej tematyki – gdybym ja miał takie informacje jak zaczynałem się uczyć powyższych technologii – oszczędziłbym ok 4 godzin szukania rozwiązań (oczywiście piszę o django i sqlalchemy).

 

Tagi: , , , , ,

Komentarze: 2 do “Kodowanie UTF-8 w python (django, pylons, sqlalchemy, mako)”

  1. 1 SeeM

    Podobnie ja z Zope 2.x.
    :
    W pliku konfiguracyjnym zope.conf w katalogu instancji stosuję podobna taktykę – zamiana wszystkiego co się na na Unicode (zapewne tracę trochę na wydajności, ale jest wygoda). Niestety interfejs ZMI trąci średniowieczem, przez co pojawiają się czasem błędy związane z konwertowaniem utf-8 na ascii. Co ciekawe Plone działa świetnie bez dłubania w konfiguracji, ale zanim znajdę co takiego wymyślili minąłby miesiąc.

  2. 2 riklaunim

    Można też dodać pliczek /usr/lib/python*/sitecustomize.py o kodzie:

    import sys
    sys.setdefaultencoding(’utf-8′)

Napisz komentarz