Python - mysqldb 插入 Unicode 失败

1 投票
2 回答
3006 浏览
提问于 2025-04-16 07:19

我在使用Python 2.6.1和mysql 5.1,操作系统是osx snow leopard。

在我的Python代码中连接数据库时,我设置了:

use_unicode=True,charset = "utf8"

但是mysql告诉我:

mysql> SHOW VARIABLES LIKE "character_set%";
+--------------------------+--------------------------------------------------------+
| Variable_name            | Value                                                  |
+--------------------------+--------------------------------------------------------+
| character_set_client     | latin1                                                 |
| character_set_connection | latin1                                                 |
| character_set_database   | latin1                                                 |
| character_set_filesystem | binary                                                 |
| character_set_results    | latin1                                                 |
| character_set_server     | latin1                                                 |
| character_set_system     | utf8                                                   |
| character_sets_dir       | /usr/local/mysql-5.1.52-osx10.6-x86_64/share/charsets/ |
+--------------------------+--------------------------------------------------------+
8 rows in set (0.00 sec)

所以这一部分没问题。

我的表结构是定义为utf8的。

CREATE TABLE `urls` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `url` varchar(300) DEFAULT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `url_idx` (`url`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;

我的语句是这样的:

insert("INSERT INTO urls (url) VALUES (%s)", (url, ))

但是当我用一个unicode字符串时,我遇到了错误。

UnicodeEncodeError: 'ascii' codec can't encode character u'\xb4' in position 7: ordinal not in range(128)

我完全不知道该怎么办……

2 个回答

0

对我来说,我会修改mysql的默认设置。怎么做呢?

首先,打开 my.cnf 文件,然后在[mysqld]这一部分添加两行,像这样:

[mysqld]
32 #
33 # * Basic Settings
34 #
35 user            = mysql
36 pid-file        = /var/run/mysqld/mysqld.pid
37 socket          = /var/run/mysqld/mysqld.sock
38 character-set-server = utf8
39 collation-server = utf8_unicode_ci

最后的两行(第38和第39行)就是我添加的内容。接下来,重启你的mysql服务器,记得重新创建你的数据库和表。这样做之后,我觉得应该就能正常工作了。我试过,确实有效。

2

问题不在于你的数据库,实际上根本没有到那一步。你这里依赖的是Python的字符串处理:

insert("INSERT INTO urls (url) VALUES (%s)" % (url, ))

千万不要这样做。 这样做不好,因为你不仅试图把一个Unicode字符串插入到一个ASCII字符串中,还让自己面临SQL注入攻击的风险。相反,你应该这样做(假设你的insert函数对应MySQLdb中的某个调用):

insert("INSERT INTO urls (url) VALUES (%s)", (url, ))

这样做的不同之处在于,你现在让MySQLdb来插入这些值,这样可以确保它们会被正确编码和加上引号。

撰写回答