我有一个python脚本,从MySQL的utf-8表导出数据到一个文本文件。 这是做这项工作的代码
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();
我也试过这个
line += '"%s";' % str(daten[i][j]);
和
line += '"%s";' % daten[i][j];
而现在我不明白的部分:
通常这个脚本应该被cron作业调用。 但是当我从一个包含变音符(如ä,ö或ü)的表中读取varchar时,脚本就会终止。 我通过将脚本的输出传输到一个文件来检查。
因此,我通过简单地input“python myscript.py”来手动调用脚本来testing脚本,它运行得很好,没有任何问题。
所以我的猜测是这个问题并不是真的在剧本本身,而是在某种程度上在cron环境中。
希望你们中的任何人都可以给我build议。 我完全困惑。
任何帮助表示赞赏。
—————-回复评论1:
感谢与语言环境的提示。
首先我在标准shell上写了“locale”。 它给了我以下输出:
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
然后我用“crontab -e”编辑了cron文件并添加了下面一行
*/1 * * * * locale > /home/user/locale.ouput
这个cronjob的输出是:
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=
那么,这可能是问题? 我该如何解决这个问题?
你用unicode(daten[i][j])将行解码为unicode。 当你没有编码时,Python使用系统默认值,当你通过cron运行脚本时,可能是ascii。
无论哪种方式,您都必须提供数据库使用的实际编码。 你可以使用unicode(daten[i][j], dbencoding) ,或者让你的数据库适配器直接给你unicode。
顺便说一句:可能有一百万个工具从数据库查询中生成CVS文件,MySQL甚至还内置了这个工具。 另一方面,你的代码是相当脆弱的,因为你不会逃避任何事情。
我很确定这是问题。 MySQL将查看您的语言环境设置,以确定要返回值的字符编码。我还知道,在ISO-8859-1中编码时,带有元音变音的拉丁字符不是有效的UTF-8字符,如果解码器尝试解码他们(并没有一个区域设置您的数据库客户端模块可能是默认的)。 我还没有尝试过,我不知道你使用的是什么版本的Python,但使用python locale返回这个链接: http ://docs.python.org/library/locale.html所以。 我会尝试
import locale locale.setlocale(locale.LC_ALL, 'de_DE.UTF-8')
在导入你的数据库连接模块之前 ,你的脚本的一开始,看看是否有效。
好的,我现在知道问题是什么 它与代码没有任何关系,好吧,以前已经清楚,但本地语言variables是问题。
在cron作业中,编码被设置为POSIX,而在正常的SHELL模式下,编码被设置为UTF-8。 所以我把所有的编码从UTF-8改为POSIX,并运行我的脚本。 令人惊奇的是,在cron环境中也发生了同样的错误。 所以现在我逐步改变编码,我的意思是variables的variables,并检查我的脚本是否运行。
首先我改变了
export LANG = de_DE.UTF-8
并运行脚本保持相同的错误。 之后,我改变了
导出LC_CTYPE =“de_DE.UTF-8”
然后脚本工作得很好。 没问题。
所以这就是问题所在。 现在如何在我的cron环境中更改这个variables? 我已经在代码中尝试过了
locale.setlocale(locale.LC_CTYPE, 'de_DE.UTF-8')
但是这没有用。
我该如何改变?