Python и MySQL / Windows - Первые грабли

Грабли, на которые я наступил при работе с мусклом из питона под виндой

, хотя почти всё здесь жестко к винде не относится и применимо ко всем ОС.

  1. import MySQLdb

    Не знаю почему, но у меня эта строчка не работала. mysql-python был установлен с помощью setuptools:

    easy_install mysql-python

    Из site-packages/.egg я вытащил всё в site-packages. Ну и убрал упоминание про egg из easy_install.pth, конечно.

    Заработало!

    На #python сказали, что у меня, наверно, были проблемы с самим файликом .egg, или с PYTHON_PATH.

  2. INSERT в никуда

    Тут всё совсем просто. База InnoDB, по-умолчанию включены транзакции, модуль MySQLdb их по-умолчанию начинает. Нужно либо делать connection.commit() после cursor.execute(), либо, как мне больше понравилось, сделать connection.autocommit(True).

  3. INSERT в левой кодировке

    Проблема кодировок и MySQL уже обсуждалась, тогда это был PHP, сегодня Python, всё иначе, прошло много времени, проблема кодировок живет. Извините, отступление.

    Удивительно, блядь, сколько еще понадобится времени, чтобы убрать нахер все кодировки и придти к единому соглашению. UTF-8 это позволяет. Не нравится — хакей, я тоже не против UTF-16. Файловые системы умеют сжимать файлики прозрачно. Даже в HTTP пришли к какому-то перемирию со сжатием (deflate vs. zlib или как там). Какие кроме размера могут быть недостатки, я вас спрашиваю? Скорость работы со строками? Да задействуйте уже наконец свои простаивающие сутками 4 ядра. 16 ядер и гигов памяти на десктопе это не фантастика, это завтра.

    Ближе к делу. Я сторонник параметризованных запросов. Потому что я не желаю знать об оборачивании строк кавычками. Это не моя проблема.
    В питоновском DB-API существует несколько способов указывать параметризованные запросы. Самые распространённые: ? и %s.
    Модуль 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”.

    Заработало! Записи вставляются и вынимаются как надо.

    Успехов вам.