Pull to refresh

Comments 11

В мире Rails наблюдается постепенный переход от фикстур к фабрикам.

Думаю, у вас тоже они уже появились.
Кажется, появился, но прошел мимо меня незамеченным.

Насколько я понял из вашего описания, речь идет о проекте factory girl. Для Django есть клон по имени factory boy и похожий по назначению инструмент django-any от kmmbvnr.

Да, речь о фабриках типа Factory Girl, Machinist или Blueprint. У фабрик свои достоинства, с ними обычно удобнее писать тесты.
Спасибо за наводку. Согласен с тем, что управление fixtures в проекте — это отдельная головная боль, и замедление исполнения тестов — не самое страшное из того, с чем приходится сталкиваться. Сами же мы используем кучу самописных функций типа make_test_user или make_order, которые частично эту проблему снимают.
Проблема в том, что в любом более-менее сложном проекте используются database-dependent штуки. Например, использовать PostgreSQL и не пользоваться ее возможностями, например, window functions (которые в одном view позволили мне сократить количество запросов с 210 до 7), просто расточительно. Есть ситуации, где просто не обойтись, например, без SELECT FOR UPDATE.

А PostgreSQL для тестов никак не ускорить. Шаманства с fsync и выносом базы на ramdisk не приносят ощутимой выгоды по времени исполнения тестов. :(
Вовсе и не в любом. Наша панель управления хостингом, например, нетривиальный проект, но мы не делаем с базой ничего такого, что не мог бы делать Django ORM. Есть у нас отдельный проект, который собирает и агрегирует всякую статистику — там тоже за пределы ORM выбираемся только, чтобы построить индексы.

И дело тут, наверное, не столько в проекте, сколько в разработчике. Когда знаешь, как использовать молоток, всё кажется гвоздем. Уверен, большинство проблем с нестандартными запросами могут быть довольно успешно решены денормализацией и кешированием.
ОРМ хороший и действительно на нем можно сделать почти все, что угодно, вопрос — какой ценой в плане производительности. Один порядок это не страшно особенно учитывая какой overhead создает ОРМ даже при самых оптимистичных сценариях, но когда речь идет о 5-6 порядках и операции такие, что кэш бесполезен (пример: берем все записи из другой таблицы, подключенные к текущей по FK, суммируем int поле у них, и если сумма ниже определенного порога, то удаляем основную запись со всеми зависимыми), то тогда в силу вступают хаки, либо приходится разводить в базе избыточность, ориентированную на оптимизацию при массовых операциях, например, каждый раз при изменении ссылающихся записей пересчитывать эту сумму и хранить ее в явном виде.

При таком подходе код моделей начинает активно разрастаться и в определенный момент, выловив в нем особо мерзкий баг, понимаешь, что ну его нахрен, надо было писать raw sql и не мучиться.
При такой сложной базе я бы предпочел вместо initial fixtures использовать напрямую дампы БД, да, это базозависимое решение, но есть и плюсы.

Если нам просто нужно просоздавать таблицы, ключи и сделать небольшое наполнение еще можно думать, но с джанговскими fixtures все очень печально даже при дампах среднего размера (100-200 мб), например у меня есть проект, где нужно полностью загружать КЛАДР в качестве исходных данных (в некоторых таблицах под 1m записей). Оснастки дохнут.

Соответственно нам нужно всего-ничего вспомогательных скриптов — слив текущего стейта БД в дамп для тестирования и создание из дампа тестовой базы при запуске теста.

В случае с sqlite автор как раз о таком подходе и пишет, но sqlite я использую только для совсем «карманных» проектов, так как в проектах побольше часто появляются агрегации вроде арифметического среднего, которые sqlite не поддерживает. А делать заглушки и разделять функционал в зависимости от используемого типа БД — нет уж, увольте.
Собственно, манипуляции с объектами connection в sqlite — это решение, которое вообще завязано на базу всеми руками и ногами. Полностью согласен, вариант dump-restore для быстрой инициализации выглядит более естественным, особенно в том случае, если нужно использовать базу, отличную от sqlite.

Продолжая защищать sqlite, замечу, что никаких проблем с получением среднего арифметического там нет, и это значение можно получать через ORM. Вот доказательство
Да, я ошибся, перепутал с разбросом, и его можно серьезно прокачать с помощью плагинов, чтобы разница не ощущалась.

Наезжать я на него совсем не хотел, для своих целей БД отличная особенно на фоне всяких firebird, для небольших сайтиков как раз использую и не парюсь, так как очень удобно с развертыванием и бэкапами — перекинул файл БД и все. Жаль, что после пересечения sqlite предела 10mb, то начинается беда с быстродействием, если она живет на диске.
Я бы не стал использовать SQLite в качестве тестовой базы. Хотя бы потому, что у текстовых полей не проверяется max_length. Или потому, что не проверяется наличие объекта по ForeignKey (при загрузке из fixtures). Таких подводных камней много
Sign up to leave a comment.

Articles