Mam skrypt w języku Python, który eksportuje dane z tabeli mysql utf-8 do pliku tekstowego. Oto kod, który wykonuje zadanie
csvDatei = codecs.open( csvDateiName, "w", "utf-8" )
...
cursor = db.cursor();
sql = "select * from %s.%s;" % (dbAusgang, tabelle)
cursor.execute(sql);
...
daten = cursor.fetchall();
for i in xrange(len(daten)):
line = '';
for j in xrange(len(daten[i])):
line += '"%s";' % unicode(daten[i][j]);
line = line[:-1];
line += '\n';
csvDatei.write(line);
csvDatei.close();
Próbowałem również tego
line += '"%s";' % str(daten[i][j]);
i
line += '"%s";' % daten[i][j];
A teraz część, której nie rozumiem:
Zwykle ten skrypt powinien być wywoływany przez zadanie cron. Ale kiedy czytam varchara ze tabeli zawierającej umlaut, taki jak ä, ö lub ü, skrypt po prostu się kończy. Sprawdziłem to, przesyłając dane wyjściowe skryptu do pliku.
Dlatego przetestowałem skrypt, wywołując go ręcznie w powłoce, wpisując po prostu „python myscript.py” i działa on doskonale bez żadnych problemów.
Domyślam się, że problem tak naprawdę nie leży w samym skrypcie, ale raczej w środowisku cron.
Mam nadzieję, że ktokolwiek z was udzieli mi porady. Jestem całkowicie zdezorientowany.
Każda pomoc jest mile widziana.
---------------- Odpowiedź na komentarz 1:
Dzięki za podpowiedź do ustawień regionalnych.
Najpierw napisałem „locale” na standardowej powłoce. Dało mi to następujące dane wyjściowe:
dhl@srv1093:~$ locale
LANG=de_DE.UTF-8
LC_CTYPE="de_DE.UTF-8"
LC_NUMERIC="de_DE.UTF-8"
LC_TIME="de_DE.UTF-8"
LC_COLLATE="de_DE.UTF-8"
LC_MONETARY="de_DE.UTF-8"
LC_MESSAGES="de_DE.UTF-8"
LC_PAPER="de_DE.UTF-8"
LC_NAME="de_DE.UTF-8"
LC_ADDRESS="de_DE.UTF-8"
LC_TELEPHONE="de_DE.UTF-8"
LC_MEASUREMENT="de_DE.UTF-8"
LC_IDENTIFICATION="de_DE.UTF-8"
LC_ALL=de_DE.UTF-8
Następnie edytowałem plik cron za pomocą „crontab -e” i dodałem następującą linię
*/1 * * * * locale > /home/user/locale.ouput
Dane wyjściowe tego cronjob jest:
dhl@srv1093:~$ cat locale.ouput
LANG=
LC_CTYPE="POSIX"
LC_NUMERIC="POSIX"
LC_TIME="POSIX"
LC_COLLATE="POSIX"
LC_MONETARY="POSIX"
LC_MESSAGES="POSIX"
LC_PAPER="POSIX"
LC_NAME="POSIX"
LC_ADDRESS="POSIX"
LC_TELEPHONE="POSIX"
LC_MEASUREMENT="POSIX"
LC_IDENTIFICATION="POSIX"
LC_ALL=
To może być problem? Jak mogę to naprawić?
locale
są takie same wewnątrz crona.Odpowiedzi:
Dekodujesz linie do Unicode
unicode(daten[i][j])
. Gdy nie podajesz żadnego kodowania, Python używa domyślnego systemu, który prawdopodobnie jest ascii po uruchomieniu skryptu przez cron.W obu przypadkach należy podać rzeczywiste kodowanie używane przez bazę danych. Możesz użyć
unicode(daten[i][j], dbencoding)
zamiast tego lub uzyskać adapter bazy danych, który da ci kod Unicode bezpośrednio.Btw: Prawdopodobnie istnieje milion narzędzi, które generują pliki CVS z zapytań do baz danych, MySQL ma to nawet wbudowane. Z drugiej strony twój kod jest raczej delikatny, ponieważ nie uciekasz w ogóle.
źródło
Jestem pewien, że to jest problem. MySQL przyjrzy się twoim ustawieniom regionalnym, aby określić kodowanie znaków do zwrócenia wartości. Wiem również, że znaki łacińskie z umlautami, gdy są zakodowane w ISO-8859-1, nie są poprawnymi znakami UTF-8, a każdy dekoder zawiedzie, jeśli spróbuje dekodować (bez zestawu ustawień narodowych moduł klienta db może być domyślny). Nie próbowałem tego i nie wiem, jakiej wersji Pythona używasz, ale Google
python locale
zwrócił ten link: http://docs.python.org/library/locale.html So. spróbowałbymna samym początku skryptu przed zaimportowaniem modułu łączności db i sprawdź, czy to działa.
źródło
Okej, teraz dowiedziałem się na czym polega problem. Nie ma to nic wspólnego z kodem, dobrze, to już wcześniej było jasne, ale problemem są zmienne języka lokalnego.
W zadaniu cron kodowania są ustawione na POSIX, aw normalnym trybie SHELL kodowania są ustawione na UTF-8. Zmieniłem więc kodowanie z UTF-8 na POSIX i uruchomiłem skrypt. I niespodzianka, ten sam błąd występuje w środowisku cron. Więc teraz zmieniam kodowanie krok po kroku, mam na myśli zmienne po zmiennej i sprawdzam, czy mój skrypt działa, czy nie.
Najpierw się zmieniłem
eksport LANG = de_DE.UTF-8
i po uruchomieniu skryptu pozostał ten sam błąd. Potem się zmieniłem
eksport LC_CTYPE = "de_DE.UTF-8"
a potem skrypt działał absolutnie dobrze. Bez problemów.
To jest problem. Jak teraz zmienić tę zmienną w moim środowisku cron? Próbowałem już w kodzie
Ale to nie zadziałało.
Jak to zmienić?
źródło
LANG=de_DE.UTF-8
aLC_CTYPE="de_DE.UTF-8"
.export LC_CTYPE="de_DE.UTF-8"; myscript.py