开发者

Python - mysqldb inserting unicode fails

Python 2.6.1, mysql 5.1 on osx snow leopard.

In开发者_开发技巧 my python code to connect I am doing; use_unicode=True, charset = "utf8"

mysql tells me

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)

So we are all good there. My table structure is defined as 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;

My statement is like

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

but with a unicode string I get an error

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

I am clue less....


The problem is not your database. It doesn't even get that far. You are relying on Python's string manipulation here:

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

Never do this. It is bad because not only are you trying to insert a unicode string into an ASCII one, you are also leaving yourself open to SQL injection attacks. Instead, do this (assuming your insert function maps to some call in MySQLdb):

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

The difference is that you are now getting MySQLdb to insert the values, thus ensuring they will be encoded and quoted properly.


For me, I would change the default setting of mysql. How to? Open my.cnf and add two lines in the session [mysqld] like this:

[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

the last two line (line 38 and 39) are what I add. And then, restart you mysql server, and remember recreate you database and tables. After doing this, I think it should works. I have tried it and it did work.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜