Apr. 24th, 2008

тень, метро, огонь, домик, торт, черный

Python & MySQL. 3 первые грабли (с решениями)

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


  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 или как там). Какие кроме размера могут быть недостатки, я вас спрашиваю?


    Ближе к делу. Я сторонник параметризованных запросов. Потому что я не желаю знать об оборачивании строк кавычками. Это не моя проблема.
    Модуль 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”.


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



    Успехов вам.

Dec. 17th, 2007

тень, метро, огонь, домик, торт, черный

Every build you break




Every Build You Break feat. Police



Every build you break
Or refactoring you make
Every mock you fake
You little snake

I'll be watching you

Every Stand Up meeting
I believe you're cheating
Every Unit test
Pains my chest

I'll be stopping you

Or can't you see?
This is scaring me
It would be so strange
If my job will change

Every iteration,
Continuous integration
Now the client's here
Everything they hear
Man it bothers me

Or can't you see
Nothing comes for free
Every test you write
Is a waste of bytes

Every class you make
Every build you break
Every mock you fake

I'll be watching you

Every class you make
Every build you break
Every mock you fake

I'll be watching you