Liquibase
Не буду разжевывать то что и так везде разжевано, просто запишу тут некоторые вещи.
Если нужно управлять ченджсетами вне контекста java-приложения, то это можно сделать непосредственно через утилиту liquibase.exe.
Для начала нужно установить liquibase на компьютер.
Затем добавить в директорию lib драйвер postgre-jdbc (желательно версии не ниже 9.6, а то будут потом проблемы).
Затем запускать из директории проекта.
Применение файла _.xml (если это обновление уже применено, то второй раз уже не применяется):
liquibase --changeLogFile=meapp /src/main/resources /liquibase/db/changesets/_ .xml --url jdbc:postgresql: //localhost :5432 /ccprod --username postgres -- password 1 --logLevel 5 update |
При этом история применения обновлений сохраняется в двух служебных таблицах: databasechangelog и databasechangeloglock.
Вместо update можно применять другие команды:
history — показать историю обновлений (https://docs.liquibase.com/commands/community/history.html)
rollbackCount 1 — откатить одно последнее обновление (https://docs.liquibase.com/workflows/liquibase-community/using-rollback.html?Highlight=rolling%20back)
updateTestingRollback — тот же update, но с тестированием отката. Но работает странно: не следит что база сохраняет консистентность
В качестве тестового файла можете использовать этот:
< databaseChangeLog xsi:schemaLocation=" < changeSet id = "myid-0" author = "knastnt" > < createTable tableName = "test_table" > < column autoIncrement = "true" name = "form_id" type = "integer" /> < column name = "form_type" type = "varchar(255)" /> < column name = "form_type_ru" type = "varchar(255)" /> < column name = "send_to_ab_flag" type = "BOOLEAN" /> < column name = "ab_title_flag" type = "BOOLEAN" /> < column name = "is_initial" type = "BOOLEAN" /> < column name = "is_update" type = "BOOLEAN" /> < column name = "send_to_bc_flag" type = "BOOLEAN" /> </ createTable > </ changeSet > < changeSet id = "myid-1" author = "knastnt" > < insert tableName = "test_table" > < column name = "form_type" value = "notification" /> < column name = "form_type_ru" value = "Уведомление" /> < column name = "send_to_ab_flag" valueBoolean = "false" /> < column name = "ab_title_flag" valueBoolean = "false" /> < column name = "is_initial" valueBoolean = "false" /> < column name = "is_update" valueBoolean = "false" /> < column name = "send_to_bc_flag" valueBoolean = "false" /> </ insert > < rollback > < delete tableName = "test_table" > < where >form_type='notification'</ where > </ delete > </ rollback > </ changeSet > </ databaseChangeLog > |
Если мы сделаем update этому файлу, то по порядку каждый ченджсет применится (если только уже не был применен). При этом в истории (history) появится два ченджсета. Если после этого сделать
rollbackCount 1, то произойдёт откат последнего ченджсета (исчезнет запись из таблицы). Если применить
rollbackCount 1 снова, то откатится ещё один ченджсет (удалится вся таблица). Можно применить просто
rollbackCount 2.
Надо заметить, что rollback описан только в одном ченджсете. Это потому что liquibase умеет генерировать скрипты для отката самостоятельно (как в случае первого ченджсета). Со вторым ченджсетом liuqibase не справился и rollback пришлось писать руками. Можно попробовать удалить явный роллбэк руками и запустить команду отката — liquebase ругнётся что не смог.
Однако, если ченджсеты применены приложением, откатить из через cmd просто так не получится, т.к. относительные пути к ченджсетам будут разные, и как их привести к единому виду — я так и не разобрался. Ещё можно как-то делать через maven, но тоже как-то не зашло…
Насчет написания ченджсетов для приложения с нуля, я пришел к выводу что проще делать через spring.jpa.hibernate.ddl-auto=create, а потом создавать ченджсеты автоматически на основе имеющейся БД:
liquibase --url jdbc:postgresql://localhost:5432/cclocal --username ccuser --password 123321 --logLevel 5 --changeLogFile=dbchangelog.xml generateChangeLog |
таким образом сгенеритуется ченджсет в файл dbchangelog.xml