liquibase - database structure versioning
TRANSCRIPT
Piotr ’Athlan’ Pelczar
Freelancer: vgroup.pl, athlan.plgoldenline.pl/[email protected]
Agenda
1. Problem wersjonowania struktur baz danych
2. Przedstawienie narzędzia Liquibase3. Instalacja4. Pierwszy zrzut bazy, tworzenie tagów5. Database diff, tag6. Rollback7. Preconditions8. Dobre praktyki9. Integracja z Maven i Eclipse
Problem
• Baza danych musi być integralna podczas developmentu.
• Jak utrzymać jej integralność?• Jak pozbyć się problemu supportowania
developerów?• Problem branchowania i mergeowania
zmian wprowadzanych podczas równoległego rozwoju aplikacji.
Czym jest Liquibase?
• Niezależna od bazy danych biblioteka.• OpenSource.• Dostępna z linii poleceń.• Do śledzenia i zarządzania zmianami w
bazie danych.• Zmiany są zapisywane w plikach XML.
Wspierane bazy danych
• MySQL• PostgreSQL• Oracle• MS-SQL• Sybase Enterprise• Sybase Anywhere• DB2• Apache Derby
• HSQL• H2• Informix• InterSystems
Caché• Firebird• SAPDB• SQLite
http://www.liquibase.org/databasesWarto się zapoznać z issues.
Format zmian
• Jako plik XML• Obsługuje ponad 40 rodzajów zmian• W tym raw SQL, co jest otwartą furktą• Można uruchamiać komendy shell
http://www.liquibase.org/manual/refactoring_commands
Format zmian
Format zmian
• Zmiany są również przechowywane lokalnie w bazie danych w tabeli databasechangelog
Współbieżność pracy
• Współbieżność jest zagwarantowana poprzez wpisy w tabeli databasechangeloglock
Uruchamianie Liquibase
Możliwość uruchomienia Liquibase z poziomu:
• Ant• Maven• Spring Framework (jako bean w kontekście)• Grails• Servlet Listener• Command Line• Integracja z Hibernate
Instalacja
1. http://www.liquibase.org/download2. Rozpakowujemy3. Pobieramy odpowiedni driver JDBC do
bazy danych, np. postgresql-9.1-902.jdbc4.jar
Instalacja
4. W bieżącym katalogu tworzymy pusty liquibase.properties z wpisem:
classpath=D:\\Programs\\Liquibase\\ postgresql-9.1-
902.jdbc4.jar
Nadpisuje on wartości z linii poleceń, można zmienić lokalizację za pomocą flagi --defaultsFile
http://www.liquibase.org/manual/command_line#using_a_liquibaseproperties_file
Wymagania
1. Java 1.5 lub nowsza2. Poprawnie skonfigurowany classpath oraz
JAVA_HOME3. Tak, aby Java była dostępna z polecenia:
java -version
4. Liquibase jest uruchamiane jako archiwum JAR:
java -jar liquibase.jar
Po rozpakowaniu
Pierwszy zrzut bazy danych
liquibase--url=jdbc:postgresql://localhost:5432/ handlowcy--username postgres--password root--changeLogFile="schema.xml"generateChangeLog
http://www.liquibase.org/manual/generating_changelogs
Pierwszy zrzut bazy danych
Ograniczenia, w sposób automatyczny nie są zrzucane:
• Procedury składowane• Funkcje• Triggey
• Jest możliwość wykonywania swoich zapytań SQL, ale nie będą przenośne.
http://www.liquibase.org/manual/generating_changelogs
Załadowanie schematu bazy
liquibase--url=jdbc:postgresql://localhost:5432/ handlowcy_dev--username postgres--password root--changeLogFile="schema.xml"update
Wygenerowanie zapytań SQL
liquibase--url=jdbc:postgresql://localhost:5432/ handlowcy_dev--username postgres--password root--changeLogFile="schema.xml"updateSQL > changes.sql
Nadeszły zmiany, diff
Sprawdzenie zmian, które nastąpiły:
liquibase--url=jdbc:postgresql://…--username postgres--password root--referenceUrl=jdbc:postgresql://…--referenceUsername postgres--referencePassword rootdiff
Nadeszły zmiany, diff
Generujemy zmiany, diffChangeLog
liquibase--url=jdbc:postgresql://…--username postgres--password root--referenceUrl=jdbc:postgresql://…--referenceUsername postgres--referencePassword root--changeLogFile=changelog-DATE-ath.xmldiffChangeLog
Diff danych
liquibase--url=jdbc:postgresql://…--username postgres--password root--referenceUrl=jdbc:postgresql://…--referenceUsername postgres--referencePassword root--changeLogFile=changelog-DATE-ath.xml--diffTypes=datadiffChangeLog
Diff uwagi
Diff obsługuje:
• Missing/unexpected tables, views, columns• Missing/unexpected primary keys, unique
constraints• Missing/unexpected foreign Keys• Missing/unexpected sequences, indexes• Column definition differences (data type, auto-
increment, etc.)• View definition differences• Data differences (limited), not checked by
default
Nadeszły zmiany, diff
Diff nie obsługuje:
• Non-foreign key constraints (check, etc)• Stored Procedures• Data type length*
* Testowano: Zmiany długości varchar w PostgreSQL są wykrywane.
Nadeszły zmiany, diff
• Ważnym jest, żeby dobrze interpretować „reference”.
Z naszej perspektywy baza produkcyjna jest główną, a rererence jest developerska.
Jeżeli odwrócimy, naturalną konsekwencją jest wygenerowanie DROP’ów zamiast CREATE’ów.
• Umieszczanie daty i nazwy dewelopera w nazwach plików changelogów to dobry nawyk:2012-11-24-athlan.xml.
• Przy zbiorczych change’ach pliki te jednoznacznie są identyfikowane nie tylko w Liquibase, ale na repozytorium git czy SVN, można je łatwiej mergeować.
Nadeszły zmiany, diff
• Raz wykonany changeSet już nigdy nie zostanie powtórzony (identyfikowany po author oraz id).
• Nie ma poprawiania XML na repo.
Tagowanie bazy danych
1. W pliku XML
<tagDatabase tag="NAZWA"/>
2. Z poziomu linii poleceń
liquibase--url=jdbc:postgresql://…--username postgres--password roottag NAZWA
Rollback
Tryb Komenda Tryb SQL
Do taga rollback<tag>
rollbackSQL<tag>
Data rollbackToDate <date>
rollbackToDateSQL <date>
Ilość changeset’ów
rollbackCount <number>
rollbackCountSQL <number>
Rollback
liquibase--url=jdbc:postgresql://…--username postgres--password rootrollback tag
rollbackSQL tag > rollback.sql
Rollback
• Większość operacji ma komplementarne sobie operacje odwrotne.
• Jeżeli nie mają, lub chcemy podjąć inne akcje, do changeset’a dodajemy tag <rollback>
• Są zapisywane w bazie danych.
Rollback
Rollback
• Przykładowy procedure
Preconditions
Warunki, które muszą być spełnione, aby nastąpił cały zestaw changeset’ów lub pojedynczy z nich.
Przydają się, gdy:• Osoba przygotowująca changelog ma jakieś
założenia.• Zapewnia ich przestrzealność.• Umożliwia sprawdzenie danch, bądź
parametrów.• Decyduje, które chengesety są uruchamiane,
a które nie.
Preconditions
Preconditions
Preconditions
Możliwe preconditions:
• columnExists• tableExists• viewExists• indexExists• sequenceExists• primaryKeyExistsdbms• runningAs
• changeSetExecuted• sqlCheck• changeLogPropertyDefin
ed• customPrecondition
(classNameimplementuje interfejs liquibase.precondition.CustomPrecondition)
Dobre praktyki
1. Trzymaj changelog’i spięte <include> zawarte w master.xml i wykonuj master’a
Integracja z Maven: pom.xml• Tworzymy główny pom.xml• Przykład dotyczy modułu common-
model
Integracja z Maven: pom.xml
Integracja z Maven: pom.xml
Integracja z Maven: pom.xmlKompilacja Maven z changesetami:
mvn install:liquibase
Piotr [email protected]
Pytania?
1. Database diff, tag2. Rollback3. Preconditions4. Dobre praktyki5. Integracja z Maven i Eclipse6. Inne…