Python & MySQL. 3 первые грабли (с решениями)
import MySQLdb
Не знаю почему, но у меня эта строчка не работала. mysql-python был установлен с помощью setuptools:
easy_install mysql-python
Из site-packages/.egg я вытащил всё в site-packages.
Ну и убрал упоминание про egg из easy_install.pth, конечно.Заработало!
На #python сказали, что у меня, наверно, были проблемы с самим файликом .egg, или с PYTHON_PATH.
INSERT в никуда
Тут всё совсем просто. База InnoDB, по-умолчанию включены транзакции, модуль MySQLdb их по-умолчанию начинает. Нужно либо делать connection.commit() после cursor.execute(), либо, как мне больше понравилось, сделать
connection.autocommit(True).INSERT в левой кодировке
Проблема кодировок и MySQL уже обсуждалась, тогда это был PHP, сегодня Python, всё иначе, прошло много времени, проблема кодировок живет. Извините, отступление.
Удивительно, блядь, сколько еще понадобится времени, чтобы убрать нахер все кодировки и придти к единому соглашению. UTF-8 это позволяет. Не нравится — хакей, я тоже не против UTF-16. Файловые системы умеют сжимать файлики прозрачно. Даже в HTTP пришли к какому-то перемирию со сжатием (deflate vs. zlib или как там). Какие кроме размера могут быть недостатки, я вас спрашиваю?
Ближе к делу. Я сторонник параметризованных запросов. Потому что я не желаю знать об оборачивании строк кавычками. Это не моя проблема.
Модуль MySQLdb использует %s параметры. Подпихнуть ему %d на число у меня, почему-то не получилось. Но можно всё равно передавать числа, как будто это строка. Так вот, я пишуsql = """INSERT INTO `table`
(`name`, `info`, `length`)
VALUES (%s, %s, %s)
;"""
sql_params = (u'меня зовут Вова', u'Я знаю три слова', 17)
cursor.execute(sql, sql_params)
Обратите внимание, параметры - строки в Unicode. В рабочем скрипте они у меня получались из запроса, .decode('utf-8'), но это неважно. MySQLdb должен сам уметь класть в базу строки в нужной кодировке. Мы работаем с Unicode.А он работает с latin1. Он не знает, что у нас в начале скрипта
# -*- coding: utf-8 -*-, что у нас кодировка сервера, базы utf-8. Он знает про свой latin1. Нельзя винить, всё логично и последовательно.Итак, чтобы заставить модуль кодировать строки во что нужно, я написал
connection.set_character_set('utf8')
Забавно выглядят два слова set. Обратите внимание. Не “utf-8”, а “utf8”.Заработало! Записи вставляются и вынимаются как надо.
Успехов вам.