Kodowanie UTF-8 w python (django, pylons, sqlalchemy, mako)
- Mateusz Żeromski | 2008-05-11 | Python
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).
1 SeeM 2008-05-15 14:05:25
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 riklaunim 2008-12-08 10:23:57
Można też dodać pliczek /usr/lib/python*/sitecustomize.py o kodzie:
import sys
sys.setdefaultencoding(’utf-8′)