我正在运行一个 Django 1.4.2/Python 2.7.3/MySQL 5.5.28 站点。该站点的一个特点是管理员可以向服务器发送一封电子邮件,该服务器通过 procmail 调用 Python 脚本,该脚本解析电子邮件并将其扔到数据库中。我维护该站点的两个版本——一个开发站点和一个生产站点。两个站点都使用不同但相同的 vitualenvs(我什至都删除了它们并重新安装了所有软件包以确保)。
我遇到了一个奇怪的问题。完全相同的脚本在开发服务器上成功,在生产服务器上失败。它失败并出现此错误:
...django/db/backends/mysql/base.py:114: Warning: Incorrect string value: '\x92t kno...' for column 'message' at row 1
我很清楚 Django 的 unicode 问题,我知道这里有很多关于这个错误的问题,但我确保从一开始就将数据库设置为 UTF-8:
mysql> show variables like "character_set_database";
+------------------------+-------+
| Variable_name | Value |
+------------------------+-------+
| character_set_database | utf8 |
+------------------------+-------+
1 row in set (0.00 sec)
mysql> show variables like "collation_database";
+--------------------+-----------------+
| Variable_name | Value |
+--------------------+-----------------+
| collation_database | utf8_general_ci |
+--------------------+-----------------+
1 row in set (0.00 sec)
此外,我知道每一列都可以有自己的字符集,但该message
列确实是 UTF-8:
mysql> show full columns in listserv_post;
+------------+--------------+-----------------+------+-----+---------+----------------+---------------------------------+---------+
| Field | Type | Collation | Null | Key | Default | Extra | Privileges | Comment |
+------------+--------------+-----------------+------+-----+---------+----------------+---------------------------------+---------+
| id | int(11) | NULL | NO | PRI | NULL | auto_increment | select,insert,update,references | |
| thread_id | int(11) | NULL | NO | MUL | NULL | | select,insert,update,references | |
| timestamp | datetime | NULL | NO | | NULL | | select,insert,update,references | |
| from_name | varchar(100) | utf8_general_ci | NO | | NULL | | select,insert,update,references | |
| from_email | varchar(75) | utf8_general_ci | NO | | NULL | | select,insert,update,references | |
| message | longtext | utf8_general_ci | NO | | NULL | | select,insert,update,references | |
+------------+--------------+-----------------+------+-----+---------+----------------+---------------------------------+---------+
6 rows in set (0.00 sec)
有谁知道我为什么会收到这个错误?为什么它发生在生产配置而不是开发配置下?
谢谢!
[编辑 1]
需要明确的是,数据也是相同的。我向服务器发送一封电子邮件,然后 procmail 将其发送出去。这是 .procmailrc 的样子:
VERBOSE=off
:0
{
:0c
| <path>/dev/ein/scripts/process_new_mail.py dev > outputdev
:0
| <path>/prd/ein/scripts/process_new_mail.py prd > outputprd
}
process_new_mail.py 有 2 个副本,但这只是因为它是受版本控制的,因此我可以维护两个独立的环境。如果我区分两个输出文件(包含收到的消息),它们是相同的。
[编辑 2] 实际上我刚刚发现 dev 和 prd 配置都失败了。不同之处在于开发配置会静默失败(可能与DEBUG
设置有关?)。问题是其中一条消息中有一些 unicode 字符,Django 出于某种原因对它们感到窒息。我在进步……
我尝试编辑代码以将消息显式编码为 ASCII 和 UTF-8,但它仍然无法正常工作。不过,我越来越近了。