LINUX.ORG.RU

[БД] есть какие-то средства сравнения двух баз?

 


0

1

день добрый.

хочется что-то вроде diff-а для двух баз, есть такие штуки?

выхлоп хочется видеть в виде комманд на изменение, типа «alter table ...», «drop function; create function ...» и т.д.

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

Pg делает бэкап в какой-то текстовый формат. Сделай два дампа, сделай им diff.

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

diff покажет только разницу (если порядок выгрузки будет совпадать, что, имхо, не обязательно), сам же alter он не сделает.

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

а ты сортирни выхлоп. По-моему, например, у mysqldump даже были встроенные средства для этого(это нужно для создания эффективных индексов при инсерте).

На крайняк сам выгрузи с нужной сортировкой в csv и сравни.

true_admin ★★★★★
()

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

Наши програмеры делают это вручную. Каждое изменение делается сразу в виде альтера, забыть не позволяют тестеры. Если тестеров нет — воспитывай силу воли. А вообще, любую базу можно сдампить в виде набора альтеров и инсертов, обычно это умеют даже клиентские приложения. Если найдёшь подходящего — напиши такой дампер сам, хоть на перле, это много времени не займёт (это действительно просто). Потом diff между двумя такими дампами будет для тебя как раз тем, что тебе надо.

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

> базу можно сдампить в виде набора альтеров и инсертов

Имею в виду, дампить создание таблицы как просто таблицы без полей, а потом добавлять столбцы, секвенсы и индексы альтерами. Описания всех таблиц можно получать, используя API драйвера.

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

> воспитывай силу воли

имхо так воспитается только геморрой.

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

таблицы — да. триггеры? хранимки?

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

> триггеры? хранимки?

только через drop trigger —> create trigger, но да, их тоже можно сдампить. А вообще, если уж всё равно пересоздавать триггер полностью, то не стесняйся, дропай все триггеры. У нас большая часть подобных объектов объединены в пакеты, если одна функиця из пакета изменилась — пересоздаём весь пакет.

Или можно почитать man diff, слышал, там есть возможность выводить только названия функций, в которых были сделаны изменения.

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

> есть масса гуевых тулзовин - just google it

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

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

> У нас большая часть подобных объектов объединены в пакеты, если одна функиця из пакета изменилась — пересоздаём весь пакет.

что такое пакет в терминах субд? как в постгресе: схема? отдельная схема для хранимок?

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

> что такое пакет в терминах субд? как в постгресе: схема? отдельная схема для хранимок?

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

name_no ★★
()

Yandex в maven-репозитории на scala-tools.org опубликовал какую-то библиотеку под названием mysqldiff. Не знаю, что это, но, может быть, то, что надо.

Zenom ★★★
()

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

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

> на каждое изменение можешь делать sql файл например, с нужными альтерами и инсертами

я хочу автоматизацию этого процесса.

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

Для firebird есть ibexpert, он умеет делать такой скрипт.

Могу рассказать, как я пишу и тестю базы.

Исходники процедур, триггеров и представлений хранятся в файлах. Раньше это был MS SQL, набор файлов с расширением SQL и простой рукописный make-файл, вызывающий isql.exe для каждого изменённого файла, с учётом зависимостей.

Кроме того, имеется файл «alter.txt», в который заносятся все скрипты для модификации. Например, если добавлено новое поле, иногда его нужно чем-то заполнить более сложным, чем значение по умолчанию. Или исправить какой-то косяк. У каждой строки в alter.txt есть пометка, на каких базах этот alter был выполнен, а на каких - нет, это позволяет не потеряться (баз у меня бывает от двух до четырёх, в зависимости от ситуации, сейчас вот их три).

Также имеется файл tables.sql, где задана текущая структура таблиц с комментариями к каждому полю. Когда нужно добавить поле, оно меняется в tables.sql и пишется запрос в alter.txt.

Ещё нужно бы вести текстовый журнал всего, что происходит с БД, я стараюсь, но часто забываю.

Сейчас я работаю с firebird. Простые makefiles не прокатывают, т.к. в firebird объекты жёстко линкуются друг с другом и нельзя (в отличие от MS SQL) дропнуть объект, на который есть ссылки. В принципе, можно было бы синхронизировать базы с помощью ibexpert, но это не совсем технологично.

Поэтому имеется прога на лиспе, которая умеет сама разбирать зависимости firebird. Также имеется определение словаря в файле tables.lisp, где ещё внесены разные дополнительные метаданные, типа заголовков полей для форм (правда, генератор форм я так и не сделал, но метаданные для клиентской стороны всё же генерируются). В остальном всё осталось по прежнему: исходные тексты серверной части хранятся в файлах, теперь они называются *.sql.lisp, также имеется файл alter.lisp, где вносится лисповая команда на каждое изменение в БД. Лисповая команда лучше скрипта тем, что она может быть интерактивной или падать в дебаггер для исправления ситуации.

Существуют также средства сверки:
1. Я могу сверить свой tables.sql с реальной субд с помощью, зачитав структуру БД из системных таблиц, для этого написал спец.средство.
2. Когда мне надо убедиться, что базы совпадают, я генерирую (ibexpert-ом) скрипты обеих баз и сравниваю их.
3. Когда мне надо убедиться, что залиты последние версии исходников из текстовых файлов, я вызываю функцию лиспа, которая всё разбирает и собирает от начала и до конца.
4. Если нужно поменять какую-то связанную группу хранимых процедур, я загружаю один лисповый файл - хорошо в ходе интерактивной разработки.

Технология (в обоих воплощениях) вполне масштабируема. Сейчас у меня в базе примерно 600 таблиц, 600 процедур и 130 триггеров. Надёжность не 100%, но ошибки, в общем-то, возникают по моей вине, а не по вине самой технологии. Старая база на MS SQL была ненамного меньше.

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

> Исходники процедур, триггеров и представлений хранятся в файлах. [ ... ] Кроме того, имеется файл [ ... ] Также имеется файл ...

много файлов...

Технология (в обоих воплощениях) вполне масштабируема.

лисповые скрипты где-то живут?

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

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

alter trigger ...
update ...

эти два предложения нельзя переставить местами и в самой базе нигде не хранится порядок действий по maintainance базы. Развитие базы - это процесс. Обычная программа - это функция своих исходников, её можно сбилдить в любой момент. Но база не является функцией своих метаданных, поскольку метаданные меняются, данные тоже меняются и эти два процесса взаимосвязаны. Если ты просто синхронизировал метаданные, это не гарантирует, что твоя тестовая и боевая база будут одинаковы «по смыслу». Т.е., тебе по любому нужен файл alter.txt, в котором будет описан именно процесс развития твоей базы, как совокупности метаданных и данных.

У меня каждый alter помечен, например, 2010-11-28.1. База знает список alter-ов, которые к ней применены. Если я второй раз пытаюсь применить уже применённый патч, она будет ругаться. Ты можешь сделать подобный механизм и даже более навороченный. Например, хранить версию метаданных, версию alter-ов и автоматически проверять, что порядок выполнения alter-ов правильный. Но всё равно что-то придётся делать руками. Есть ли это для твоей базы - нужно сначала узнать, какой у тебя сервер, обычно лучшие средства по работе с СУБД пишутся для конкретного сервера.

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

> Кроме того, изменение базы должно проходить в соврешенно определённом порядке.

т.е. это вполне можно описать программно.

всё равно что-то придётся делать руками.

да ради бога. щас _весь_ diff (90% это alter table и drop/create function/view/etc...) делается руками и это задалбывает.

какой у тебя сервер

постгрес.

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

> много файлов...
Это продуманная и выстраданная минимально сложная технология. Файлы необходимы, поскольку только их можно записать в систему контроля версий.

лисповые скрипты где-то живут?

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

Впрочем, лисп тут необязателен, можно использовать любой интерактивный ЯП (хотя лисп - самый интерактивный ЯП и его просто использовать удобнее всего, если ты его знаешь).

На самом деле, написать такой сборщик не слишком сложно. Сложно это оказалось в firebird из-за жёстких связей между объектами. Версия для MS SQL была отлажена где-то за полдня. Правда, плохо то, что исходник конкретного объекта нужно искать грепом. Но это тоже не так страшно.

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

> тестовой базе этот констрейнт проходит, в боевой - не проходит.

транзакция отвалися, случится rollback, вывалится соответствующий лог. не вижу проблемы.

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

> Тоже в файлах.

да это понятно :)

я в смысле «слить и посмотреть» :)

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

т.е. это вполне можно описать программно.

Ну я же ещё раз говорю, есть апдейты, которые ты делаешь вручную. Например, появилось новое поле, которое нужно загрузить откуда-то из внешнего источника. Сначала ты будешь это проверять на тестовой базе, потом подготовишь маленькую программку, которая будет делать это на рабочей. Потом ты должен в конкретный момент (может быть, ночью при отсутствии пользователей) это запустить и проверить результат. Обычно тестовая база отличается от рабочей, например, по соображениям безопасности или просто оттого, что между «мерджами» в боевую базу вводятся новые данные. То, что прошло на тестовой, может сломаться на боевой.

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

постгрес

С постгресом не работал никогда.

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

> есть апдейты, которые ты делаешь вручную. Например, появилось новое поле, которое нужно загрузить откуда-то из внешнего источника.

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

Потом ты должен в конкретный момент (может быть, ночью при отсутствии пользователей) это запустить и проверить результат.

ничего страшного, я потерплю.

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

> транзакция отвалися, случится rollback. не вижу проблемы
Утром придут пользователи, а база - в нерабочем состоянии, т.к. половина обновления прошла (далеко не всегда обновление базы помещается в одной транзакции). Проблемы тут нет, если ты контролируешь выполнение и вовремя поправишь. Но как ты будешь запускать скрипт с середины? Всё равно ручная работа неизбежна.

я в смысле «слить и посмотреть» :)

Не понял вопроса.

den73 ★★★★★
()

а что за субд-то? сферическая в вакууме? по google://schemadiff+postgres сразу нашлось. вот и вот

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

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

Ну, в общем, спорить я не буду (слава бога, тут не защита диссера), я просто рассказал свой опыт.

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

schemadiff может довольно долго работать на больших метаданных (говорю не про postgres, а про ibexpert). Но для маленькой базы, скорее всего, то, что надо.

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

Поправка - говорю не про schemadiff, а про ibexpert. Хотя в любом случае, чтобы получить diff, нужно как минимум полностью вытянуть с сервера метаданные, а их может быть много (у меня скрипт метаданных содержит 2.7 мб и вытягивается секунд 30, а diff генерируется, наверное, минуты полторы две, потом ещё исполняется секунд 30). Но, конечно, по сравнению с ручным трудом и это тоже рай. Правда, ibexpert написан на Дельфи, а schemadiff - на Java, так что, наверное, ещё на порядок медленнее было бы при моих масштабах.

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

> сразу нашлось. вот и вот

одно — список хотелок, второе у меня падает.

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

> в общем, спорить я не буду

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

> я в смысле «слить и посмотреть» :)

Не понял вопроса.

посмотреть на это дело (в сырцах) где-то (в интернетах) можно? линк?

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

ААААА, вот ты о чём. Хм. Ну, теоретически я секрета не делаю из этого, но нужно провести немалую работу для издания, поскольку не хватает документации и всё такое. Кроме того, в коде кое-где разбросана конфиденциальная инфа моих работодателей. Если тебе это реально нужно, я могу попробовать, но это много времени займёт. Тебе будет проще написать такую систему самому на своём любимом ЯП. Кстати, я ещё забыл, чем хорошо хранить метаданные БД в файлах - по ним легче анализировать логику работы БД, т.к. можно грепом найти ссылки на любой объект. Хотя сейчас в ibexpert есть вменяемый поиск по метаданным и просмотр зависимостей, всё это достаточно быстро и надёжно работает. Когда я работал с MS SQL, у меня не было таких инструментов и непонятно, как бы я вообще поддерживал серверную часть, если бы метаданные были не в текстовых файлах. Многое зависит от того, какие инструменты есть для postgres и насколько хорошо они работают. Если, например, найти ссылки на данную процедуру занимает 5 секунд - это одно, если 5 минут - это другое.

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

Мммм, хотя это становится интересным. Если действительно всё так плохо и нету даже такого средства для postgres, то может быть, имеет смысл сделать то, что я делаю, в приличном виде под postgres?

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

Хотя чёто я не понял, первое средство - это вовсе не список хотелок. Тебя напрягает, что оно работает в командной строке, что ли? Но какая разница, если она автоматически выдаёт скрипт?

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

> Тебя напрягает, что оно работает в командной строке, что ли?

меня напрягает то, что оно у меня падает с нулевым результатом.

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

посмотри на pg_comparator. Есть так же патч на pg_dump который добавляет ORDER BY при дампе. Вряд ли ты будешь патчить посгрес, но, на всякий случай, ссылку приведу: http://www.mail-archive.com/pgsql-hackers@postgresql.org/msg150504.html

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

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

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

> патч на pg_dump который добавляет ORDER BY при дампе

да хрен с ней, с сортировкой select-а. схему-то как сравнить?

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

хз как сравнивать, но я бы делал все преобразования через миграции. Вот тогда сравнивать было бы сильно проще.

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

> я бы делал все преобразования через миграции.

хоть в девелопменте остались муд^W граждане, которые стартовый пост и треды н читают. я рад, чесслово ))

нахрена это все делать руками?! 2 базы, почему никого не интересует как их diff-нуть? все внезапно поперлись в тродулюбивые быдлокодеры? проект на $your_language ты тоже ведешь в виде пачки рукописных патчей?

да выдрачивает же делать каждый раз alter/create/drop и следить за всеми изменениями, при том, что таких изменений в день может быть много (еще и растянуто на день-два-три), а финальное, которое можно засунуть в БД в виде запроса, одно, не?

и это если человек я один. если нас хотя бы трое и какой-то мудак забыл про одну процу. искать зае^W очень быстро устанешь.

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

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

true_admin ★★★★★
()

Именно такую штуку я писал на ПХП в качестве тестового задания при устройстве на работу. Исходников нет.
Собираюсь начать заново писать.
Написать такое не очень сложно, ну и не просто.

p.s. На phpclasses.org скрипт для сравнения css файлов получил первое место и приз. Но это было 3 года назад.

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