LINUX.ORG.RU

Как учитывать изменения в структуре БД в VCS?

 , ,


1

3

Подробнее о проблеме: вот я пишу какое-либо веб-приложение. У меня есть ряд текстовых файлов (.php, .js, - не важно) в каталоге, все изменения в котором отслеживаются каким-нибудь git'ом. НО процесс развития веб-приложения - это не только развитие кода, но и развитие БД.

Внимание вопрос, как отслеживать такие изменения в БД, через VCS, так, чтоб я мог откатить, клонировать и тому подобные пряники.

Предполагаемые решения: сразу спроектировать структуру БД так, чтоб потом не потребовалось учитывать это в системе контроля версий - К. О. мне уже это говорил, мне хочется большего.

Написать скрипт, который будет сохранять перед коммитом структуру БД в такой же текстовый файлик, с тем чтоб изменения в нем так же отслеживались VCS'ом. Так и планирую сделать, но сперва решил воззвать к коллективной мудрости, а ну как уже реализовано или есть более мудрое решение проблемы, о котором я не подумал.

★★★★★
Ответ на: комментарий от vertexua

Короче полностью автоматический менеджмент базы не выгорел

Да я понял уже принципиальную невозможность решения этой задачи в общем случае.

Но в этом свете, ИМХО, самое простое и логичное каждый раз удалять базу и создавать с новой структурой. А где нужно мигрировать с данными - там это - творческая задача для программиста.

pihter ★★★★★
() автор топика
Ответ на: комментарий от pihter

Но в этом свете, ИМХО, самое простое и логичное каждый раз удалять базу и создавать с новой структурой

Но все же хотелось бы сохранить данные :)

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

vertexua ★★★★★
()
Последнее исправление: vertexua (всего исправлений: 1)
Ответ на: комментарий от pihter

ну я это так понял, что два приложения сразу юзают одну СУБД

х-й, это когда _одно_ приложение способно работать с различными РСУБД

anon1984
()
Ответ на: комментарий от pihter

но, блджад, они мне дают деньги, и это заставляет меня развивать проект вот таким вот методом.

// достал щит, закрываться от летящих помидор...

ага. От диванных теоретиков.

drBatty ★★
()
Ответ на: комментарий от anon1984

это когда _одно_ приложение способно работать с различными РСУБД

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

pihter ★★★★★
() автор топика
Ответ на: комментарий от drBatty

А вот ревизий кода DDL Over9000(и каждая ревизия DDL ведёт добавление хотя-бы одного лишнего метода).

Зачем хранить DDL ? Если DDL на изменение структуры формируется автоматически по заранее известному синтаксису ?

Если ты всё таки хранишь DDL, то в итоге то что ? Применять ты его как будешь ?

TEX ★★★
()
Ответ на: комментарий от vertexua

Действительно, если ты удалил столбик или слил два числовых столбика в их сумму, то вернуть назад нельзя

можно. С потерей данных конечно. Ну мы же про структуру?

Данные как-то иначе хранятся, НЕ в VCS. Вот их восстановление — только из бекапов, и действительно не тривиально. Но и не нужно обычно, потому-что старые данные потеряли актуальность сами по себе, даже если все столбцы целые.

Короче полностью автоматический менеджмент базы не выгорел, не тривиальная это задача.

задача не сложная, но IRL попросту не нужная. Ты какую цель от VCS хочешь получить? Зачем тебе откат?

drBatty ★★
()
Ответ на: комментарий от pihter

которая точно для этой версии скрипта, и их синхронность будет гарантироваться тем, что они внутри _одного_ коммита в VCS?

Дык версия измененного класса миграции у тебя так же внутри того же комита.

TEX ★★★
()
Ответ на: комментарий от vertexua

Но все же хотелось бы сохранить данные

зачем?

Только система должна точно знать, что речь идет о переименовании, а не удалении старого столбца и добавлении нового пустого. И это будет известно если пользователь в каких-то гуях или консоли явно напишет rename.

ВНЕЗАПНО: с файлами та же беда в VCS. Попробуй переименовать файлик, hg догадается, но предупредит, что «наверное файл переименовался». А если новый появляется, дык hg и не предупреждает.

drBatty ★★
()
Ответ на: комментарий от anon1984

это когда _одно_ приложение способно работать с различными РСУБД

а это не проблема. Сейчас ВСЕ приложения напрямую с DDL не работают. В php есть например PDO. В других ЯП — другие костыли. Причём применение костылей обязательно, даже если СУБД одна.

drBatty ★★
()

Много камментов, не читал. Вместо этого опишу схему, которая применяется у нас.

Для работы с базой используется редактор, который позволяет видеть sql-команды вносимых в схему изменений. У нас используется СУБД postgres, клиент pgadmin.

Все правки последовательно записываются в файлик, причем есть правило записывать все правки, происходящие в процессе работы над схемой, даже те, которые потом в этом же файле отменяются - это хорошая практика, позволяет избежать ошибок при релизах. Файлы хранятся в структуре вида NNNN.TASK-XXX/MM.sql, где TASK-XXX - номер задачи из трекера, NNNN и MM - просто инкрементирующиеся числа. Например: 0012.TASK-1532/01.sql. Сделано это для того, чтобы, если развернуть структуру директории и отсортировать, sql-накаты шли в правильной последовательности.

При деплое самописная утилита берет необходимые файлы накатов, сортирует их, объединяет в один файл и накатывает в одной транзакции через psql. Используется преимущество постгреса - мускуль не позволяет откатить DDL-запросы в транзакции (раньше не позволял, не знаю, как сейчас, давно уже с ним не работал). Правки по версии либо накатываются все сразу, либо ни одна не накатывается, тогда берем сгенеренный файл и смотрим. Но на практике случаев проблем с sql-накатами при релизах - один на 100.

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

heisenberg ★★
()
Ответ на: комментарий от TEX

Зачем хранить DDL ? Если DDL на изменение структуры формируется автоматически по заранее известному синтаксису ?

оно у тебя меняется к текущему состоянию от прошлого состояния _того же_ приложения. А зачем мне прошлое состояние?

Если ты всё таки хранишь DDL, то в итоге то что ? Применять ты его как будешь ?

ну я могу получить рабочую копию старого приложения, что-бы найти баг, или сделать форк, или даже могу пойти иным путём. Причём прошлая версия у меня будет работать _правильно_. Будут неправильные данные, только и всего.

drBatty ★★
()
Ответ на: комментарий от drBatty

о том и речь. вносим изменения на уровне модели (PDO и др. костыли, в моем случае - Django ORM), подсистема миграций их отслеживает, профитом имеем сгенерированные cross-rdbms скрипты миграций, которые позволяют двигаться по ревизиям модели БД.

anon1984
()
Последнее исправление: anon1984 (всего исправлений: 1)
Ответ на: комментарий от TEX

Дык версия измененного класса миграции у тебя так же внутри того же комита.

да. В виде, который не пригоден для использования.

drBatty ★★
()
Ответ на: комментарий от vertexua

Там фоточки на фоне ковра моих пользователей.

в твоём коде? Тогда извини. Мы о разном.

drBatty ★★
()

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

Legioner ★★★★★
()
Ответ на: комментарий от heisenberg

0012.TASK-1532/01.sql

ага. Это когда VCS не было, именно так исходники и хранили. В 80х годах прошлого века. Ваще-то 30 лет прошло, не?

drBatty ★★
()

Например, в Rails для твоей проблемы придуманы миграции. Это такие файлики, меняющие структуру БД, добавляющие/изменяющие таблицы и пр. Они хранятся в VCS и Rails позволяет с их помощью откатывать структуру на сколько угодно шагов назад-вперёд.

Alve ★★★★★
()
Ответ на: комментарий от Legioner

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

ну примерно как у меня. Только у меня сохраняется один скрипт, в котором все таблицы создаются, а заботится о версиях VCS. Не нужно папок и мамок. Если нужна версия ревизии №666 — просто создаёшь БД из этой ревизии.

drBatty ★★
()
Ответ на: комментарий от Alve

Они хранятся в VCS и Rails позволяет с их помощью откатывать структуру на сколько угодно шагов назад-вперёд.

читай тему.

Проблема в том, что откатывать назад должны не какие-то файлики, а VCS.

drBatty ★★
()

Есть 2 принципиальных способа это сделать:

1) Хранить в VCS DDL для текущей версии схемы, на которой оттестировано приложение. Изменения накатываются так: с помощью sql diff тулзы делаешь разницу в DDL текущей схемы, и схемы в VCS, получаешь патч. Этот патч обязательно ревьюишь, тестируешь, накатываешь при деплое в прод.

2) Хранить в VCS инкрементальные патчи. Патчи тестируются так: они накатываются на прод копию, полученная схема сравнивается со схемой, на которой оттестирована новая версия приложения.

Всякие СУБД-незасимые миграции это уже просто сахарок обычно ко второму способу. Смысл в них есть, если реально нужна независимость от СУБД.

dizza ★★★★★
()
Ответ на: комментарий от drBatty

В таком виде оно хранится в VCS. Но совместная работа с этими файлами запрещена.

Ты ни черта не понял из моего каммента, перечитай еще раз.

heisenberg ★★
()
Ответ на: комментарий от drBatty

да. В виде, который не пригоден для использования.

Это еще почему ?

Выгрузил нужную ревизию, получил код класса миграции. Запустил, возможно даже не сам, а тулза по разворачиванию проекта.

Вот что получиться непригодным для использования так это DDL. Ибо потом нужно ручками соображать какой из DDL, в зависимости от СУБД, нужно взять и где то его запускать. Скорее всего руками.

TEX ★★★
()
Ответ на: комментарий от drBatty

ну я могу получить рабочую копию старого приложения, что-бы найти баг, или сделать форк, или даже могу пойти иным путём.

Выгружаешь нужную версию миграции, запускаешь на пустой базе. Получаешь DDL.

Это если тебе зачем то потребовалось смотреть DDL, хбз зачем, обычно если возникает такая необходимость - то это значит что дела идут максимально хреново, и программер накосячил везде, даже в DDL

TEX ★★★
()
Ответ на: комментарий от drBatty

Проблема в том, что откатывать назад должны не какие-то файлики, а VCS.

VCS должна откатывать СУБД ? Опаньке ...

TEX ★★★
()
Ответ на: комментарий от drBatty

не какие-то файлики, а VCS.

Ну тогда кроме велокостылей решения не будет. СУБД это одно, VCS изначально проектируются управлять «какими-то файликами». Разве что пусть sqlite-базу хранят прям в дереве проекта, но это дурость ещё большая, имхо.

Alve ★★★★★
()
Ответ на: комментарий от heisenberg

Ты ни черта не понял из моего каммента, перечитай еще раз.

перечитал. Ты хранишь Over9000 файлов с diff'ами. Да, синтаксис там в этих diff'ах SQL'ный, но это всё равно diff'ы, ибо — изменения. Я и не понимаю, зачем это делать, если можно хранить один файл со всей структурой, а его историю будет хранить VCS?

drBatty ★★
()
Ответ на: комментарий от TEX

Выгрузил нужную ревизию, получил код класса миграции. Запустил

ну вот то-то и оно: «запустил». А по моему способу я _сразу_ получаю _структуру_ нужной ревизии. И могу работать с этими структурами средствами VCS. (например я могу их смержить. Ты тоже можешь смержить два класса, но у тебя получится ерунда, которая потребует нудного ручного редактирования)

Вот что получиться непригодным для использования так это DDL. Ибо потом нужно ручками соображать какой из DDL, в зависимости от СУБД, нужно взять и где то его запускать. Скорее всего руками.

что там думать?

s.mysql
s.pgsql
s.sqlite3
и так далее. Пихай куда надо.

drBatty ★★
()
Ответ на: комментарий от TEX

Выгружаешь нужную версию миграции, запускаешь на пустой базе. Получаешь DDL.

всё правильно — лишний уровень абстракции. скрипт->DDL->СУБД, потому-как ты всё равно общаешься с СУБД с помощью DDL. Абстракция «скрипт» в данном случае не нужна.

drBatty ★★
()
Ответ на: комментарий от TEX

Проблема в том, что откатывать назад должны не какие-то файлики, а VCS.

VCS должна откатывать СУБД ? Опаньке ...

а как ещё получить _рабочую_ старую версию? С новой базой старая версия работать не будет. Значит к каждой ревизии надо приляпать свою БД (возможно пустую).

drBatty ★★
()
Ответ на: комментарий от Alve

Ну тогда кроме велокостылей решения не будет.

не будет.

drBatty ★★
()
Ответ на: комментарий от TEX

Дык версия измененного класса миграции у тебя так же внутри того же комита.

Дык, его, этот класс, руками писать нужно и пихать в мой код! Зачем он там? Там он не нужен: контроль версий - задача, которая абсолютно не относится к моей программе, это внешняя задача. Контроль версии файла кода же я туда аналогичным классом не запихиваю, а мог бы, ток зачем?

pihter ★★★★★
() автор топика
Ответ на: комментарий от heisenberg

для серьезных проектов вещь слишком ненадежная

Ну у меня не настолько серьезный :)

Я вообще gedit'ом до последнего времени обходился, а версии файлов контролировал прописывая // ver 0.1.23 в начале каждого файла. А БД - вообще по памяти, какая у меня где версия и с какими отличиями

Просто на определенном этапе развития резко стал ощущать что пора расти. Не потому что я такой крутой, а потому что стало пониматься что дело тормозит из-за этого

pihter ★★★★★
() автор топика
Ответ на: комментарий от Legioner

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

Можно, но теряются преимущества VCS: получается что за версией файлов кода будет следить она, а за версией БД - я. Хотелось бы чтоб за всем следила она.

pihter ★★★★★
() автор топика
Ответ на: комментарий от Alve

Например, в Rails для твоей проблемы придуманы миграции.

Да вот говорят что и для пыха есть, только, насколько я пока понимаю, это - ерунда какая-то...

pihter ★★★★★
() автор топика
Ответ на: комментарий от drBatty

Только у меня сохраняется один скрипт, в котором все таблицы создаются, а заботится о версиях VCS

Вот пока ничего умнее никто и не предложил. Самое логичное. Но чуток костыльно, но, по сравнению с остальным - KISS и православно

pihter ★★★★★
() автор топика
Ответ на: комментарий от dizza

Есть 2 принципиальных способа это сделать:

Да, мы тут уже холиварчик развели небольшой :)

Я-то думал, мне щас скажут: «нуб, лови тулзу, инсталишь поверх гита, даешь ей доступ к БД, и забудь про проблему»

А вот фиг мне :)

pihter ★★★★★
() автор топика
Ответ на: комментарий от TEX

VCS должна откатывать СУБД ? Опаньке ...

А почему нет-то? Это ж логично. Она же система контроля версий, ей, по идее, вообще пофиг, версию чего контролировать, хоть исходника, хоть документации, хоть любой документик вёрдовский на работе. Почему я должен версию кода контролировать одной тулзой, а версию БД - другой, при этом следить за синхронностью поручается мне, а я - косячник, я человек. Не логичнее было бы следить одновременно за версией кода и за версией структуры БД, ибо они - неделимы?

pihter ★★★★★
() автор топика
Ответ на: комментарий от pihter

нуб, лови тулзу, инсталишь поверх гита, даешь ей доступ к БД, и забудь про проблему

дык только в простых случаях можно просто взять, и поделить код и данные в СУБД. IRL они там спутанны в непонятный клубок и месиво. Простым SHOW CREATE TABLE не распарсить. Вот и нет тулузы.

Хотя, ИМХО, такого клубка и месива быть не должно. Но есть.

Не логичнее было бы следить одновременно за версией кода и за версией структуры БД, ибо они - неделимы?

проблема в том, что часто БД неделима. Даже как правило.

drBatty ★★
()
Ответ на: комментарий от pihter

насколько я пока понимаю, это - ерунда какая-то...

насколько я понимаю - ерунда

Если Рабинович будет предлагать напеть по телефону Beatles - не соглашайся.

Alve ★★★★★
()
Ответ на: комментарий от drBatty

IRL они там спутанны в непонятный клубок и месиво. Простым SHOW CREATE TABLE не распарсить.

Как-так не распарсить? Структуру таблицы? ИМХО, этого достаточно... что я не учитываю?

pihter ★★★★★
() автор топика
Ответ на: комментарий от Alve

Если Рабинович будет предлагать напеть по телефону Beatles - не соглашайся.

Я, конечно, понимаю, что могу чего-то не понимать, и, даже, наверняка, однако, никто толком мне пока не объяснил чего же я не понимаю...

pihter ★★★★★
() автор топика
Ответ на: комментарий от Legioner

Какие преимущества теряются?

А такие, например, что мне об этом париться нужно. VCS все за меня делает: я вообще забываю про проблему контроля версий, а тут мне, мало того что, самому приходится писать скрипты перехода, дак еще и самому нужно следить за синхронностью... А я, повторюсь, - человек, следовательно, ошибаюсь иногда...

pihter ★★★★★
() автор топика

Я для этого держу велосипед.

Структура базы хранится в xml'е. Среди прочего в нём есть строка

<info version='0.02' />
В самой базе в таблице настроек хранится значение версии. И в самом коде определена версия базы. При старте, проверяется соответствие версии в коде и в действующей бд. Если версии разные, то ищется xml'на с нужной для работы и в базу вносятся изменения. Если нужной xml'ны не найдено, вылетаем с ошибкой.

Таким образом для изменений в базе мне достаточно скопипастить xml со структурой, подправить его(добавив/удалив/переименовав поля) и инкрементировать версию в нём и в коде. Сама бд сменится при первом старте программы.

shell-script ★★★★★
()
Ответ на: комментарий от pihter

Скрипты перехода можно автоматизировать далеко не всегда. Если за тебя все переходы делает программа, могу только посоветовать почаще делать бэкапы, они понадобятся.

В этом, собственно, ключевое отличие БД от набора файлов и причина, почему VCS, предназначенные для файлов не работают с БД.

Legioner ★★★★★
()
Последнее исправление: Legioner (всего исправлений: 1)
Ответ на: комментарий от pihter

А почему нет-то? Это ж логично.

В каком месте логика ? Как давно VSC научилась работать в бинарными данными СУБД ?

Она же система контроля версий, ей, по идее, вообще пофиг, версию чего контролировать, хоть исходника, хоть документации, хоть любой документик вёрдовский на работе.

А вторые пять записей в таблице megatron.detail она должна контролировать ? Каким образом ?

при этом следить за синхронностью поручается мне, а я - косячник, я человек.

думаешь VSC тебе поможет не косячить ? Тха-ха-ха. Максимум она поможет найти баг, откатит ревизию. У нас уже пару раз было когда один разраб добавил поле MegaSumm типа Инт, второй разраб добавил поле поле MegaSumm типа Стринг, потом как-то задней ногой всё это смержили - и VSC радостно «сделала» в структуре таблиц два поля MegaSumm - откуда VSC-у знать что в структуре таблицы БД имя поля подразумевается уникальным ? Для неё это один фиг строчки в тексте.

Не логичнее было бы следить одновременно за версией кода и за версией структуры БД, ибо они - неделимы?

Структура версии БД <> СУБД. У нас вообще структура всегда выгружается вслед за кодом, и реально неотделима. VSC тут помогает не сильно, пример смотри выше. Один фиг от людей в конечном итоге все зависит

TEX ★★★
()
Ответ на: комментарий от pihter

VCS все за меня делает:

Ну вот скажи, VCS поймет что полученные в результате слияния два primary key это ошибка ?

TEX ★★★
()
Ответ на: комментарий от drBatty

а как ещё получить _рабочую_ старую версию?

1. Получить ревизию старой версии. 2. Загрузить её в СУБД

Второй пункт никакого отношения к VCS не имеет.

Значит к каждой ревизии надо приляпать свою БД (возможно пустую).

facepalm.jpg. То есть ты предлагаешь не только DDL хранить но и сами «чистые» БД ? В любом случае подключать и инициализировать эту «чистую» БД, один фиг будет не VCS.

TEX ★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.