metaclass: (Default)
metaclass ([personal profile] metaclass) wrote2010-06-12 07:35 am

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

Сижу думаю над шизой.
Имеется описание предметки в виде модели для кодогенерации - хитрозаколдованный набор данных, над которым работают несколько людей и по которому нужно хранить историю.
Для обычной цели "посмотреть кто в прошлом виноват и что делать" истории в виде текстовых diff вполне хватило бы, и набор данных можно представить в любом человеко-машино-читаемом виде (JSON, YAML, итд), засунув его под меркуриал и разбив на несколько файлов по отдельной модели в каждом (там моделей несколько, они зависят друг от друга и работать над ними лучше независимо).
Но вторая цель хранения истории - это генерить патчи для миграции данных, которые эта модель описывает, между версиями модели. Т.е. добавили в модель поле, пару таблиц, еще чего-нибудь навертели - нужно из этого сгенерировать аццкий SQL скрипт, который это все применит к уже работающей базе данных. А тут уже текстовых diff-ов мало.

Можно было бы сделать собственное хранение истории, благо описание самой модели хранится в ней самой и прикрутить к кодогенератору еще и генерацию триггеров аудита изменений особой проблемы нет. Но тогда будет дублирование функциональности меркуриала, причем каждое изменение будет в двух местах - в основных данных, и в логе изменений дописано в конец. Но другого разумного способа сопоставить историю типизированных данных и ее отражение в виде сhangeset-ов меркуриала я не вижу.

[identity profile] zamotivator.livejournal.com 2010-06-12 10:58 am (UTC)(link)
А что мешает написать скрипт, который использую утилиты mercrial сам пройдётся по системие контроля версий, посмотрит на diff'ы, и сгенерит всё что недо?

[identity profile] dmitry-vk.livejournal.com 2010-06-12 02:37 pm (UTC)(link)
Поддерживаю этот вариант. И, конечно, diff должен быть не текстовым построчным, а должен сравнивать структуры.

[identity profile] metaclass.livejournal.com 2010-06-12 03:08 pm (UTC)(link)
А, в принципе логично. Конвертировать ревизии в данные и сравнить.

[identity profile] zamotivator.livejournal.com 2010-06-12 03:32 pm (UTC)(link)
О чём и речь

[identity profile] gds.livejournal.com 2010-06-12 10:58 am (UTC)(link)
не про меркуриал и совсем не про diff-ориентированный подход. Наоборот, про patch-ориентированный.
В последнее время мне кажется, что схема должна строиться индуктивно от пустой схемы путём применения простых операций: ввести новую сущность, добавить аттрибут сущности, поменять тип, сделать аттрибут обязательным, и так далее. На выходе получим весьма простой способ 1. получения схемы на любой момент времени, 2. отражения этих операций на sql.
Я пока не думал в эту сторону сильно, но следил за своими действиями, когда меняю структуры в немаленькой реляционной базе данных, и вроде пока всё вписывается и всё удобно.
Не продуман вопрос об имеющихся данных: например, для пустой схемы у любой операции есть обратная, тогда как на схеме с данными после удоления аттрибута и внесения его взад данные не появятся.
Далее, про одновременную работу: для каждой пары операций очень просто определить, коммутируют ли они, и можно хорошо уменьшить количество работы / необходимость merge'ить операции от разных людей.

[identity profile] gds.livejournal.com 2010-06-12 11:00 am (UTC)(link)
если рассматривать diff-ориентированный подход, то, очевидно, требуется всё "денормализовать" так, чтобы пара строк (удалённая и добавленная) несла полную информацию о том, что поменялось. Если одна сущность раскинется более чем на одну строку, дифф рано или поздно превратится в тыкву.

[identity profile] zamotivator.livejournal.com 2010-06-12 03:33 pm (UTC)(link)
Кстати, да. Как вариант - в систему контроля версий складывать patch'и, а потом некоторой тулзой точками времени x1 и x2 получать скрипт на миграцию.

Тогда _удалять_ ничего не потребуется.

[identity profile] metaclass.livejournal.com 2010-06-12 05:38 pm (UTC)(link)
Это совпадает с моим вторым вариантом, когда хранилище для данных само по себе ведет историю изменений, т.е. дублирует функциональность контроля версий. В принципе, особой проблемы в этом наверно и нет.

[identity profile] permea-kra.livejournal.com 2010-06-12 06:41 pm (UTC)(link)
>> Т.е. добавили в модель поле, пару таблиц, еще чего-нибудь навертели - нужно из этого сгенерировать аццкий SQL скрипт, который это все применит к уже работающей базе данных.

Поставим вопрос иначе. Что мешает писать много маленьких скриптов, а потом из тестовой базы выгружать описание модели?

[identity profile] metaclass.livejournal.com 2010-06-12 06:57 pm (UTC)(link)
Модель первична, скрипты миграции - следствие.

[identity profile] permea-kra.livejournal.com 2010-06-12 06:59 pm (UTC)(link)
Что мешает описать модификации модели как набор последовательных операций, в скрипты миграции транслируемые однозначно ?

[identity profile] metaclass.livejournal.com 2010-06-12 07:09 pm (UTC)(link)
Ничего, я про это и пишу.
Просто я хочу это дело заинтегрировать с системой контроля версий, чтобы не повторять ее функциональность.

[identity profile] permea-kra.livejournal.com 2010-06-12 07:10 pm (UTC)(link)
>>Просто я хочу это дело заинтегрировать с системой контроля версий,чтобы не повторять ее функциональность.
А зачем? Если инструмент не может то, что вам надо, то нужно ли его насиловать?