2010-11-19 13 views
1

Python 2.6.1, mysql 5.1 sur osx snow léopard.Python - mysqldb insérant unicode échoue

Dans mon code python pour me connecter je fais; use_unicode = True, charset = "UTF8"

mysql me dit

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) 

Nous sommes tous bien là. Ma structure de table est définie comme 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; 

Ma déclaration est comme

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

mais avec une chaîne unicode je reçois une erreur

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

Je suis indice moins ....

+0

Quel est le classement de la colonne url? – Sam

+0

utf8_general_ci – Wizzard

Répondre

2

Le problème n'est pas votre base de données. Ça ne va même pas aussi loin. Vous comptez sur la manipulation de chaînes de Python ici:

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

Ne jamais faire cela. C'est mauvais car non seulement vous essayez d'insérer une chaîne unicode dans une chaîne ASCII, mais vous vous exposez à des attaques par injection SQL. Au lieu de cela, faites-le (en supposant que vos insert cartes de fonction à un certain appel à MySQLdb):

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

La différence est que vous êtes maintenant trouvé MySQLdb d'insérer les valeurs, assurant ainsi ils seront codés et cités correctement.

+0

Désolé mon erreur, mon code dans la question était faux. J'utilise la bonne technique comme vous le montrez, je l'ai séparé dans mon programme en deux lignes. Encore pardon. Donc, c'est autre chose. – Wizzard

+0

Dans ce cas, veuillez montrer le code actuel et le retraçage complet. –

+0

Voir mon commentaire sur Marks answer .... semble étrange – Wizzard

0

Pour moi, je voudrais changer le paramètre par défaut de mysql. Comment? Ouvrez my.cnf et ajouter deux lignes dans la session [mysqld] comme ceci:

[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 

les deux dernières lignes (ligne 38 et 39) sont ce que j'ajouter. Ensuite, redémarrez votre serveur mysql, et souvenez-vous de recréer votre base de données et vos tables. Après cela, je pense que cela devrait fonctionner. Je l'ai essayé et ça a marché.