2010-11-19 13 views
1

Python 2.6.1, mysql 5.1 auf OSX Schneeleopard.Python - mysqldb Einfügen von Unicode schlägt fehl

In meinem Python-Code zu verbinden, mache ich; use_unicode = True, charset = "UTF-8"

mysql sagt mir

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) 

Also haben wir es alle gut sind. Meine Tabellenstruktur wird als UTF-8 definiert

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; 

Meine Aussage ist wie

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

aber mit einem Unicode-String bekomme ich einen Fehler

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

Ich bin Anhaltspunkt weniger ....

+0

Wie lautet die Spaltenkollatierung der URL? – Sam

+0

utf8_general_ci – Wizzard

Antwort

2

Das Problem ist nicht Ihre Datenbank. Es kommt nicht einmal so weit. Sie verlassen sich auf Python String-Manipulation hier:

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

dies nie tun. Es ist schlecht, weil Sie nicht nur versuchen, eine Unicode-Zeichenfolge in eine ASCII-Zeichenfolge einzufügen, sondern auch SQL-Injection-Angriffen ausgesetzt sind. Stattdessen tun dies (Ihre insert Funktionskarten zu einem gewissen Ruf in MySQLdb vorausgesetzt):

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

Der Unterschied ist, dass Sie jetzt MySQLdb werden immer die Werte einfügen, wodurch sichergestellt wird sie richtig codiert und zitiert werden.

+0

Sorry mein Fehler, mein Code in der Frage war falsch. Ich verwende die richtige Technik, wie Sie zeigen, ich habe es in meinem Programm in zwei Zeilen getrennt. Entschuldigung nochmal. Also, es ist etwas anderes. – Wizzard

+0

In diesem Fall zeigen Sie bitte den tatsächlichen Code und die vollständige Traceback. –

+0

Siehe meinen Kommentar zu Marks Antwort .... scheint seltsam – Wizzard

0

Für mich würde ich die Standardeinstellung von mysql ändern. Wie man? Öffnen my.cnf und fügen Sie zwei Zeilen in der Session [mysqld] wie folgt aus:

[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 

die beiden letzten Linie (Linie 38 und 39) sind das, was ich hinzufügen. Und dann, starten Sie Ihren MySQL-Server neu, und erinnern Sie sich neu erstellen Sie Datenbank und Tabellen. Danach denke ich, es sollte funktionieren. Ich habe es versucht und es hat funktioniert.