Wersjonowanie baz danych podczas developmentu Liquibase Piotr Pelczar me@athlan.pl
Piotr Athlan Pelczar Freelancer: vgroup.pl, athlan.pl goldenline.pl/piotr-pelczar me@athlan.pl
Agenda 1. Problem wersjonowania struktur baz danych 2. Przedstawienie narzędzia Liquibase 3. Instalacja 4. Pierwszy zrzut bazy, tworzenie tagów 5. Database diff, tag 6. Rollback 7. Preconditions 8. Dobre praktyki 9. 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/databases Warto 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/download 2. Rozpakowujemy 3. 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_liq uibaseproperties_file
Wymagania 1. Java 1.5 lub nowsza 2. Poprawnie skonfigurowany classpath oraz JAVA_HOME 3. 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 root diff
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.xml diffchangelog
Diff danych liquibase --url=jdbc:postgresql:// --username postgres --password root --referenceurl=jdbc:postgresql:// --referenceusername postgres --referencepassword root --changelogfile=changelog-date-ath.xml --difftypes=data diffchangelog
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, autoincrement, 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 root tag NAZWA
Rollback Tryb Komenda Tryb SQL Do taga Data rollback <tag> rollbacktodate <date> Ilość changeset ów rollbackcount <number> rollbacksql <tag> rollbacktodatesql <date> rollbackcountsql <number>
Rollback liquibase --url=jdbc:postgresql:// --username postgres --password root rollback 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 changelogpropertydefined customprecondition (classname implementuje interfejs liquibase.precondition.custo mprecondition)
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.xml Kompilacja Maven z changesetami: mvn install:liquibase
Pytania? 1. Database diff, tag 2. Rollback 3. Preconditions 4. Dobre praktyki 5. Integracja z Maven i Eclipse 6. Inne Piotr Pelczar me@athlan.pl
Wersjonowanie baz danych podczas developmentu Liquibase Piotr Pelczar me@athlan.pl