Pull to refresh

Comments 21

Я представлял себе решение, которое сравнивает production и development БД, и создаёт, полностью самостоятельно, соответствующие миграции (SQL-файлы) с данными.

В вашем случае — разработчику также достаётся ручное отслеживание, что именно изменилось и какие изменения нужно внести в production БД. Согласен, что это намного удобнее, чем ручной цикл (особенно в плане «версионного контроля» БД), но для полной автоматизации процесса ещё есть место. :)
Автоматическая генерация с возможностью вставлять «подсказки» вручную (правда, для постгреса и без генерации откатов) — вот: github.com/DmitryKoterov/dklab_pgmigrator (сделана на основе замечательного apgdiff-а Мирослава Шульца).
Не совсем понятно, что имеется в виду под «ручным отслеживанием». Если нужно что-то изменить — вместо того, чтобы ручками править БД, напишите миграцию. Если придерживаться этого подхода и не править БД руками!, то все, что нужно будет сделать любому разработчику для приведения продакшена в актуально состояние, это набрать в консоли
./ruckus db:migrate
(за исключением случая очень больших таблиц)

Касательно инструмента, который бы сравнивал схему и самостоятельно генерировал миграционные SQL-файлы, тут достаточно сложный вопрос. Я когда-то использовал Toad for MySQL (если мне не изменяет память), но результаты были иногда просто обескураживающие (в плохом смысле).
вместо того, чтобы ручками править БД, напишите миграцию

Вот если взять пример из статьи, то написать соответствующий SQL-запрос для изменения базы получится и быстрее и нагляднее, чем «миграцию»
А теперь представьте (немного утрировано), что схема у Вас меняется несколько раз в день, в течение хотя бы полугода, и в команде хотя бы 2 человека, причем каждый может менять схему. Я думаю уже через пару недель у Вас начнутся проблемы, при использовании быстрого и наглядного подхода с SQL-запросами :) Не устанете рассказывать сокаманднику Васе, что и как Вы сегодня поменяли в базе?

На самом деле, кажется что долго с миграциями из-за большого сетапа (относительно). Через некоторое время написание миграции занимает в разы меньше времени, чем использование голого SQL.

Или это Вы к тому, что надо бы примерчик посложнее?
Я понял, в чём идея миграций, и согласен что это вещь нужная и удобная. Главное, чтобы разработчик не поленился, и создал миграцию для своих изменений.

В комментарии, видимо я неправильно сформулировал мысль: хотелось бы иметь решение, которое проверяет, две БД, и различия в них выводит в соответствующий SQL-код (миграцию и откат, соответственно два файла). Как-то так.

Например:
Разработчик закончил пились свою фичу, отполировал код, и надо ему написать миграцию для БД. Он запускает скрипт, где указывает целевую БД и свою БД как источник. Скрипт сравнивает базы и генерирует два SQL-файла: миграцию и откат (что по сути является обратной миграцией с целевой БД на БД разработчика).
Остаётся только заполнить соответствующие файлы/методы/функции в коде миграции — и вуаля. :)

DmitryKoterov, спасибо за ссылку, гляну.
Я когда на работу устраивался — это было моим тестовым заданием — написать скрипт, который сравнит 2 mysql базы и выдаст sql файл, которые приведёт одну базу к состоянию другой. (структура + опционально данные)
В общем примерно за час я накидал более-менее работоспособный прототип, дальше делать не стал — так взяли :)) при желании за вечер можно написать полностью :)
Не уверен, что тут все так просто.
Если данные не интересуют, то это можно просто дропнуть исходную БД, а потом создать заново из дампа целевой. Если все же хотелось бы сохранить какие-то данные, причем не только те, что находятся в «пересечении» атрибутов таблиц исходной и целевой БД, я прямо так сразу и не могу предложить адекватного решения. Например, как отработать такую ситуацию, без какой-либо дополнительной информации?
Была следующая схема у таблицы test, например:
a -> int
b -> string
c -> string

Стала
a -> int
d -> string
e -> string

Где c была переименована в d, а b была переименована в e.
Эм… вы поставили меня в тупик :) Задача была несколько другая… видимо я что-то неправильно понял. Задача заключалась в выкладывании dev базы на продакшен… для этого нужны было найти отличия dev версии и сгенерировать файл, приводящий продакшн к состоянию dev версии.
В данном случае скрипт бы дропнул b и c и создал бы новые поля d и е.
Полноценный анализ, конечно, на коленке не напишешь… да и без истории изменений или человеческого вмешательства не обойтись…
Что касается конкретно того скрипта, который я писал — он создавал массивы со структурами обеих баз, сравнивал — записывал результаты сравнения в другой массив (какие таблицы и поля добавились, какие изменили свой тип или другие атрибуты, какие удалились) и на его основе генерировал sql запросы. Аналогично потом пробегал по самим данным.
Было не сложно, ибо всегда одна база была ведущая, а другая отстающая — надо было отстающую обновить до состояния ведущей, а не делать общую базу на основе обоих.
Поясните алгоритм, очень интересно.
Присоединяюсь к предыдущему комментарию Deshene.
UFO just landed and posted this here
Да, Вы правы, делает то же самое. Но, несмотря на то, что Symfony — замечательный фреймворк, свет на нем клином не сошелся, а с «голой» Doctrine, по-моему не так удобно работать в плане миграций.
Вообще сейчас большая часть современных фреймворков реализует механизм миграций в том или ином виде, и если начинать новый проект, лучше использовать готовую инфраструктуру. Описанное в статье решение — это, на мой взгляд, больше для легаси.
а с «голой» Doctrine, по-моему не так удобно работать в плане миграций.

Да ничем особо не отличается от предложенных решений.
А вот если использовать и Doctrine ORM, тогда есть возможность использовать магию

P.S. Если кто не знает — Doctrine — это далеко не только ORM, ORM это только один из проектов
Чтобы оно действительно напоминало рельсы, было бы неплохо иметь метод change вместо up и down
Писать постоянно миграции в обе стороны крайне напряжно. Особенно с учетом того, что очень мала веротяность что миграции вниз реально понадоятся.
Именно для этого нам и даны Pull Request'ы :)
Хотя реализация change может быть несколько затруднительна: все-таки PHP не настолько крут в метапрограммировании как Ruby.
В Yii можно глянуть реализацию behaviors и в зависимости от направления подключать разные классы с реализацией методов типа create_table. В rails миграциях почти нет никакой мета-магии.

Кстати миграции есть и в самом Yii, только ещё не видел людей, которые их там использовали.
Кстати миграции есть и в самом Yii, только ещё не видел людей, которые их там использовали.

Приятно познакомиться :)
Миграции, конечно, удобны когда работаешь в команде, но если проект делаешь сам — только лишняя трата времени на их создание.
Я бы с вами поспорил. Делаю хобби-проект сам, делаю миграции (встроенные в Yii). После нескольких обновлений базы при деплое гораздо легче запустить миграцию автоматически, чем вспоминать и делать что-то там «руками».
Рассмотрите чуть более далекую перспективу, чем первый месяц-два работы над проектом. Со временем время на ручное обновление БД при деплое приложения, или приведение тестовой БД в актуальное состояние будет занимать гораздо больше времени, чем Вы секономите при написании миграции (опять же, через пару недель написание миграции занимает не больше времени, чем соответствующии инструкции SQL).
Это я уже не говорю о том, что при «ручном» версионировании БД практически невозможно использование CI для Вашего проекта. Да и в целом, автоматизация процесса — дело благое, в идеале нужно добиться, чтобы можно было развернуть проект одной командой в консоли.
К тому же, закладываясь на то, что «проект делаю сам, зачем мне лишние трудности», Вы обрекаете себя на гораздо большие проблемы, когда, в случае успеха Вашего проекта, команда неминуемо пополнится новыми людьми.
Возможно, что я не дошел до состояния, чтобы миграция писалась быстрее чем 3 клика в phpmyadmin.

Вот как только появится второй бекенд разработчик — сразу же и создание миграций станет обязательным.
Sign up to leave a comment.

Articles