Pretius: strategiczna fuzja jako odpowiedź na współczesne wyzwania
Pretius. Budujemy mądrzej:
strategiczna fuzja jako odpowiedź na współczesne wyzwania

Poradnik Liquibase 2024: Czym jest to narzędzie i jak zacząć z niego efektywnie korzystać?

Rafał Grzegorczyk

Oracle APEX & PL/SQL Developer

  • 1 marca, 2024

Spis

[Uwaga] Ten artykuł został pierwotnie opublikowany w marcu 2021 r., ale w lutym 2024 r. został zaktualizowany o nową treść – w dużej mierze napisany od nowa.

[Uwaga] Ten artykuł został pierwotnie przygotowany w języku angielskim i został przetłumaczony na język polski.

Ten poradnik skupia się na konfiguracji Liquibase dla bazy danych Oracle, ale proces i organizacja plików są podobne w przypadku wszystkich innych baz danych obsługiwanych przez Liquibase.

Oto repozytorium GitHub, w którym znajdziesz pliki, których używam w poniższych przykładach.

Czy ten poradnik Liquibase jest dla Ciebie?

Czy ręcznie wykonujesz skrypty na swojej bazie danych? A może marnujesz czas na sprawdzanie skryptów bazy danych otrzymanych od zespołu?

Czy po tym wszystkim łączysz skrypty w jeden plik i wykonujesz je w każdym środowisku? Co z błędami wdrożeniowymi? Czy kiedykolwiek spędziłeś godziny sprawdzając, kto i dlaczego zmienił coś w bazie danych?

Możesz usprawnić to wszystko za pomocą Liquibase.

Ale co, jeśli nie możesz teraz wdrożyć całego procesu CI/CD lub polityka firmy nie pozwala na uruchamianie skryptów w określonych środowiskach? To dla Liquibase również nie problem.

Używając Liquibase, możesz:

  • Zautomatyzować skrypty wdrażania bazy danych
  • Konsekwentnie wdrażać zmiany w ten sam sposób w każdym środowisku
  • Mieć wszystkie szczegółowe informacje o wdrożeniach w jednym miejscu

Dzięki temu zyskasz:

  • Mniej błędów podczas wdrożeń
  • Zadowolonych i wydajnych programistów pracujących wspólnie na tych samych bazach danych
  • Audyt każdej zmiany, np. kto, kiedy (i dlaczego) zmienił kolumnę SHOES.SHOE_SIZE z typu danych NUMBER na VARCHAR2
  • Więcej czasu na kawę ☕️

Chcesz wiedzieć, kto, kiedy i dlaczego zmienił kolumnę w Twojej bazie danych? Czytaj dalej ten poradnik Liquibase

W serii artykułów pokażę Ci, jak zautomatyzowaliśmy proces zmian w bazie danych w Pretius przy użyciu Liquibase i GIT – zacznijmy od tego podstawowego poradnika.

Czym dokładnie jest Liquibase?

Liquibase to narzędzie typu open-source napisane w Javie. Ułatwia definiowanie zmian w bazie danych w formacie, który jest znany i wygodny dla każdego użytkownika. Następnie automatycznie generuje SQL specyficzny dla danej bazy danych.

Zmiany w bazie danych (każda zmiana nazywana jest changeset) są zarządzane w plikach zwanych changelogs. Moje przykłady będą oparte na changesetach napisanych w SQL – to najprostszy sposób na rozpoczęcie automatyzacji procesu zmian w bazie danych Oracle.

Jak działa Liquibase?

Teraz omówmy kilka podstawowych terminów i szczegółów, które pomogą Ci zrozumieć, jak działa Liquibase i co robi.

Changelogi

Liquibase używa plików changelog (w formatach SQL, XML, YAML lub JSON), aby wylistować zmiany w bazie danych w kolejności sekwencyjnej. Oto przykład changelogu:

Zrzut ekranu pokazujący Liquibase.

Powyższy przykład zawiera ścieżkę do dwóch innych changelogów (tabele countries i departments ).

Changesety

Zmiana w bazie danych nazywana jest changeset. Istnieje wiele typów changesetów, które można zastosować w bazie danych, takich jak tworzenie tabeli, dodawanie klucza głównego lub tworzenie paczki (package).

Plik departments_table.sql to changelog zawierający dwa changesety:

Ekran pokazujący Liquibase.

Legenda:

  • linia 1 –liquibase formatted sql to składnia, którą należy dodać na początku każdego nowego changelogu SQL. Liquibase wymaga tego do identyfikacji plików changelog
  • linie 2 i 13 – Te linie to identyfikatory, które unikalnie opisują każdy changeset
    • Pretius autor (author) changesetu
    • departments_table i add_col_description – unikalne identyfikatory (id) changesetu
  • linia 3 i 14 – to komentarze. Jest to opcja, a nie wymóg

Changeset jest unikalnie identyfikowany przez atrybuty autor oraz id , a także ścieżkę do pliku changelog.

Tabele śledzące

Liquibase używa tabeli DATABASECHANGELOG do śledzenia, które changesety zostały uruchomione. Jeśli tabela nie istnieje w bazie danych, Liquibase tworzy ją automatycznie.

Liquibase utworzy również tabelę DATABASECHANGELOGLOCK . Będzie ona używana do tworzenia blokad, aby uniknąć jednoczesnego uruchamiania Liquibase w Twojej bazie danych.

To wszystko, jeśli chodzi o podstawy. Dowiesz się więcej, czytając ten poradnik i analizując pokazane przykłady.

Instalacja i połączenie

Początkowy proces instalacji jest dość prosty. Nie będę go opisywał w tym artykule, ale mam kilka wpisów na moim blogu Hashnode, które przeprowadzą Cię przez to krok po kroku:

  1. Samodzielna instalacja Liquibase na Windows/MacOS + łączenie Liquibase z bazą danych Oracle (on-premise/chmura)
  2. Instalacja SQLcl z Liquibase – Pamiętaj, że nie jest to konieczne, jeśli zaczynasz używać Liquibase w całkowicie nowym projekcie. Jeśli jednak zaczynasz od istniejącego projektu, w dalszej części opiszę, jak „pobrać” obecny stan istniejącej bazy danych za pomocą SQLcl
  3. Konfiguracja kodowania UTF-8 – Jest to konieczne tylko w przypadku korzystania z systemu Windows

Konfiguracja środowiska dla tego poradnika

  • Posiadam 2 bazy danych Oracle Cloud Autonomous (wersje darmowe) – DEV oraz PROD
  • Użytkownicy HR z obiektami Human Resources są zainstalowani zarówno w środowisku DEV , jak i PROD (pobrałem obiekty HR z przykładowego repozytorium Oracle)

Ekran pokazujący Liquibase.

  • W tym poradniku zostaną wykorzystane również inne przykładowe obiekty dostępne tutaj
  • SQLcl jest zainstalowany w wersji 23.4 (zostanie użyty tylko raz – do przygotowania istniejącego projektu do użycia Liquibase)
  • Zainstalowano Standalone Open Source Liquibase 4.25.1
  • Mój główny folder repozytorium GIT, pokazany na kolejnych zrzutach ekranu, będzie nazywał się LIQUIBASE_TUTORIAL
  • Publiczne repozytorium GIT z plikami pokazanymi w tym poradniku znajduje się tutaj
  • Używam Visual Studio Code, aby ułatwić sobie pracę z plikami
  • Używam klienta FORK do pracy z repozytoriami GIT

Konfiguracja dla istniejącego projektu

Teraz pokażę Ci, jak skonfigurować wszystko dla Twojego istniejącego projektu. Będziesz musiał wykonać kilka kroków.

Upewnij się, że Twoje środowiska są identyczne (DEV=UAT=PROD)

Zaleca się, aby środowiska były identyczne przed użyciem Liquibase. Zazwyczaj zalecam dwa sposoby, aby to osiągnąć.

Jeśli uważasz, że różnice między Twoimi bazami danych są ogromne i niekontrolowane, powinieneś użyć Oracle Data Pump:

  1. Zatrzymaj wszystkie prace rozwojowe lub zakończ je i wdróż na PROD za pomocą starego procesu
  2. Usuń stare schematy, takie jak DEV i/lub UAT.
  3. Wyeksportuj aktualny schemat PROD używając Oracle Data Pump
  4. Utwórz nowe DEV/UAT używając wyeksportowanego schematu PROD
  5. W razie potrzeby zanonimizuj dane (lub w punkcie 3 wyeksportuj tylko strukturę / wyklucz niektóre obiekty)

Ewentualnie, jeśli przypuszczasz, że bazy danych są niemal identyczne i nie zajmie to dużo czasu, możesz po prostu zrobić wszystko ręcznie.

Użyj SQLcl Liquibase, aby przechwycić bieżący schemat

Utworzyłem folder DATABASE/HR/, którego użyję do przechwycenia mojego bieżącego schematu ze środowiska HR_DEV . Użyję do tego SQLcl Liquibase.

Przejdź do folderu [TWÓJ_ROOT_REPOZYTORIUM]/DATABASE/HR/ . W moim przykładzie jest to LIQUIBASE_TUTORIAL/DATABASE/HR/. Połącz się z bazą danych HR_DEV.

Ekran pokazujący Liquibase.

Aby przechwycić wszystkie obiekty mojego schematu HR , możesz użyć polecenia generate-schema:

liquibase generate-schema -split -sql

W zależności od rozmiaru bazy danych może to potrwać od kilku minut do nawet 1-4 godzin.

Ekran pokazujący Liquibase.

SQLcl Liquibase automatycznie wygenerował wszystkie obiekty mojego schematu w osobnych folderach. Pliki zostały wygenerowane w formatach XML i SQL.

Ekran pokazujący Liquibase.

Format XML jest świetny i oferuje znacznie więcej funkcjonalności Liquibase – ale nie będę go używać w tym poradniku (więcej o formatach XML przeczytasz w dokumentacji). Dlatego muszę usunąć wszystkie wygenerowane pliki XML. Można to zrobić na dwa sposoby.

Ponownie, jeśli nie masz wielu plików, możesz zrobić wszystko ręcznie. Alternatywnie możesz użyć załączonego skryptu PowerShell, który zrobi to za Ciebie, jeśli Twoja baza danych jest duża:

  • Przejdź do repozytorium tego poradnika i skopiuj skrypt HELP_SCRIPTS/POWERSHELL/remove_xml_files.ps1 do folderu głównego (LIQUIBASE_TUTORIAL w moim przypadku)
  • Usunie on wszystkie pliki XML z Twojego folderu /DATABASE/ i podfolderów

Ekran pokazujący Liquibase.

W efekcie w osobnych folderach mam tylko pliki SQL.

Dostosuj automatycznie wygenerowane pliki SQL do dalszego użytku z Liquibase – usuń string „%USER_NAME%” (to prawdopodobnie problem w SQLcl 23.4 – do potwierdzenia) ze wszystkich plików SQL i zastąp go swoją nazwą schematu.

Ekran pokazujący Liquibase.

Zrzut ekranu pokazujący Liquibase.

Dodaj składnię Liquibase do wszystkich automatycznie wygenerowanych plików SQL (tylko istniejące projekty!)

Jeśli pracujesz z istniejącym projektem, musisz dodać składnię Liquibase do wszystkich automatycznie wygenerowanych plików SQL. Możesz to zrobić ręcznie lub użyć mojego skryptu PowerShell, który zrobi to za Ciebie.

  • Przejdź do repozytorium i skopiuj HELP_SCRIPTS/POWERSHELL/add_changesets.ps1 do folderu swojego schematu (w moim przypadku jest to DATABASE/HR/)
  • Dostosuj skrypt, jeśli to konieczne, ale najpierw utwórz kopię zapasową folderu!
  • Uruchom skrypt za pomocą PowerShell

Ekran pokazujący Liquibase.

  • Kilka sekund później każdy plik SQL w Twoim repozytorium będzie miał automatycznie dodaną składnię:

Ekran pokazujący Liquibase.

Utwórz nowe changelogi, aby kontrolować swoje repozytorium obiektów

Teraz stwórzmy changelogi, aby kontrolować Twoje repozytorium obiektów. Ten krok jest niezbędny zarówno dla istniejących, jak i nowych projektów.

  • Utworzę mój główny plik changelog master.xml, który będzie odpowiedzialny za kolejność wykonywania moich plików. Plik ten znajdzie się w moim katalogu głównym:

  • Teraz muszę wskazać moje foldery z określonymi typami obiektów. Jest to ważny krok, ponieważ sposób zapisu w master.xml będzie kolejnością wykonywania. Użyję struktury folderów, która została automatycznie wygenerowana podczas przechwytywania schematu mojego obecnego projektu (patrz wyżej).

Ekran pokazujący Liquibase.

Legenda:

  • includeAll – wykonaj wszystkie pliki z podanej lokalizacji w kolejności alfabetycznej. Pamiętaj, że pliki PKB lub PKS nie są obsługiwane – preferuję używanie wyłącznie SQL lub XML. W powyższym przykładzie wszystkie pliki z folderu /SEQUENCE/ zostaną wykonane jako pierwsze, w kolejności alfabetycznej.

Ekran pokazujący Liquibase.

  • includeFile – za pomocą tego tagu wyraźnie określasz, który plik (changelog) powinien zostać wykonany. Daje to większą kontrolę nad kolejnością wykonywania plików.

Aby pokazać, jak używać includeFile, przygotowałem przykład dla wszystkich moich procedur wewnątrz folderu /DATABASE/HR/PROCEDURE/:

  • Z pliku master.xml usuwam includeAll łączące z tym folderem i zastępuję je tagami includeFile

Ekran pokazujący Liquibase.

  • Następnym krokiem jest stworzenie changelogu procedure_order.xml w lokalizacji /DATABASE/HR/PROCEDURE/

Ekran pokazujący Liquibase.

W tym przykładzie wyraźnie wskazuję, który plik powinien być wykonany w jakiej kolejności.

Możesz tworzyć takie changelogi dla wszystkich swoich folderów i używać dowolnej ich liczby.

Utwórz połączenia z DEV i PROD dla standalone Liquibase

Utworzyłem dwa połączenia, korzystając z poradnika instalacji z początku tego przewodnika. Jedno dla środowiska DEV , a drugie dla PROD .

Ekran pokazujący Liquibase.

Tylko istniejące projekty: Zsynchronizuj swoją bazę danych z Liquibase

Kolejnym krokiem jest synchronizacja istniejącej bazy danych z Liquibase – oczywiście będzie to konieczne tylko w przypadku istniejących projektów. Celem jest „poinformowanie” Liquibase, że wszystkie pliki w Twoim repozytorium już istnieją w Twojej bazie danych i pliki te nie powinny być wykonywane, dopóki ktoś nie zmieni czegoś w kodzie.

Moje dwa środowiska DEV i PROD są teraz identyczne, więc muszę je zsynchronizować – jest to tylko jednorazowy krok, gdy zaczynasz używać Liquibase w istniejącym projekcie.

Polecenie changelog-sync oznacza wszystkie zmiany w changelogu jako wykonane w Twoiej bazie danych (dowiedz się więcej w dokumentacji Liquibase).

Wykonaj w środowisku DEV

liquibase --defaults-file=dev.liquibase.properties --changelog-sync-sql

Ekran pokazujący Liquibase.

Użyłem najpierw polecenia changelog-sync-sql, aby wygenerować plik SQL i zweryfikować, co zostanie wykonane po uruchomieniu polecenia changelog-sync.

Nie użyłem filtrowania po etykietach (labels), np. –label-filter=INITIAL_SYNC, ponieważ w tej chwili chcę przechwycić wszystkie moje zmiany.

Gdyby jednak moje polecenie wyglądało tak, wynik i plik wyjściowy byłyby takie same:

liquibase --defaults-file=dev.liquibase.properties --changelog-sync-sql -label-filter=INITIAL_SYNC

Ekran pokazujący Liquibase.

Jak widzisz, Liquibase utworzy tabele DATABASECHANGELOGLOCK i DATABASECHANGELOG – ponieważ jest to pierwszy bieg Liquibase.

Co więcej, wiele wierszy zostanie wstawionych do tabeli DATABASECHANGELOG, oznaczając wszystkie changesety jako już wykonane.

Żaden inny kod bazy danych nie zostanie wykonany – brak zmian w istniejących obiektach. Pełny wygenerowany skrypt możesz zobaczyć tutaj.

Dobrą praktyką jest najpierw uruchamianie poleceń z opcją -sql i podglądanie, co się stanie, zamiast wykonywania niezamierzonego kodu.

Teraz wykonam polecenie changelog-sync.

Dwie tabele zostały utworzone, a wiersze do DATABASECHANGELOG zostały wstawione.

Zrzut ekranu pokazujący Liquibase.

Zrzut ekranu pokazujący Liquibase.

Powtórz powyższe kroki w środowisku PROD

Przed powtórzeniem kroków pamiętaj o zmianie pliku połączenia.

liquibase --defaults-file=prod.liquibase.properties --changelog-sync-sql

Zrzut ekranu pokazujący Liquibase.

Plik podglądu był w porządku, więc wykonam changelog-sync.

liquibase --defaults-file=prod.liquibase.properties --changelog-sync

Zrzut ekranu pokazujący Liquibase.

Wynik jest taki sam jak na DEV – dwie tabele zostały utworzone, a wiersze do DATABASECHANGELOG zostały wstawione. Twój istniejący projekt jest gotowy do dalszej pracy z Liquibase.

Podsumowując to, co zrobiliśmy:

  1. Korzystając z Oracle SQLcl Liquibase, przechwyciliśmy aktualny stan bazy danych do plików SQL
  2. Pliki SQL zostały dostosowane do pracy z Liquibase (dodano wymaganą składnię – ręcznie lub za pomocą załączonego skryptu PowerShell)
  3. Wykonaliśmy polecenie changelog-sync w środowiskach DEV i PROD
  4. Upewniliśmy się, że DEV i PROD to identyczne środowiska (te same obiekty, dane mogą się różnić)

Jeśli chodzi o GIT:

  1. Wszystkie moje pliki znajdują się w repozytorium GIT i reprezentują rzeczywisty punkt wyjściowy moich baz danych
  2. Pliki powinny znajdować się w gałęziach (branchach) GIT DEV oraz PROD. Gałęzie te powinny być w tym momencie równe

Zrzut ekranu pokazujący Liquibase.

Zrzut ekranu pokazujący Liquibase.

Istniejące i nowe projekty: Śledzenie zmian w bazie danych

Dobrze, masz już repozytorium GIT i bazę danych skonfigurowaną do użytku z Liquibase. Od teraz wszystkie zmiany w bazie danych będą śledzone.

Z tego powodu NIE POWINIENEŚ zmieniać żadnego z obiektów bazy danych bezpośrednio w bazie (czy to przez SQLcl, SQL Developer czy jakiekolwiek inne narzędzie). Każda zmiana powinna odbywać się poprzez zmianę w pliku SQL w Twoim repozytorium i wykonanie odpowiedniego polecenia Liquibase.

W następnej części tego poradnika dokonam różnych zmian w mojej bazie danych, aby pokazać, jak tworzyć changesety i pisać odpowiednią składnię. Wszystkie pliki i zmiany, które wprowadzę, są dostępne w publicznym repozytorium stworzonym na potrzeby tego poradnika.

Wszystkie zmiany będą najpierw tworzone i wykonywane w bazie danych DEV . Po udanych testach zmiany zostaną wprowadzone na PROD.

Szybkie przypomnienie: changeset to typ zmiany w bazie danych, np. utworzenie tabeli, modyfikacja tabeli, utworzenie paczki itp.

Do wdrażania zmian będę używać polecenia UPDATE . Bardzo dobrą praktyką jest określanie tylko jednego typu zmiany na changeset. Pozwala to uniknąć sytuacji, w których instrukcje auto-commit pozostawiają bazę danych w nieoczekiwanym stanie. Podczas uruchamiania polecenia UPDATE każdy changeset albo kończy się sukcesem, albo niepowodzeniem. Jeśli się nie powiedzie, możesz go łatwo naprawić i wdrożyć ponownie. Powinieneś także dodawać komentarze do swoich changesetów, aby wyjaśnić ich znaczenie.

Czym jest polecenie Liquibase UPDATE i jak działa?

Ale najpierw zdefiniujmy, co naprawdę robi polecenie UPDATE . Wdraża ono wszelkie zmiany w pliku changelog, które nie zostały jeszcze wdrożone w Twojej bazie danych.

Warto wspomnieć, że Liquibase nie sprawdza niczego w obiektach bazy danych. Nie sprawdzi, czy tabela, kolumna lub paczka istnieją. Nie sprawdzi, jaka wersja obiektu znajduje się w bazie danych. Jeśli jednak spróbujesz utworzyć tabelę, która istnieje, Oracle zgłosi błąd podczas wykonywania Liquibase. Skąd więc Liquibase wie, co powinno zostać wdrożone?

Kiedy uruchamiasz polecenie UPDATE , Liquibase sekwencyjnie odczytuje changesety w pliku changelog, a następnie porównuje unikalne identyfikatory – id, autor (author) i ścieżkę pliku – z wartościami w tabeli DATABASECHANGELOG . Istnieją co najmniej 3 możliwe scenariusze, które mogą wystąpić po uruchomieniu polecenia UPDATE :

  • Składnia Twojego changesetu jest nieprawidłowa (niepoprawny SQL lub PL/SQL) i Twoja baza danych Oracle zgłosi błąd.
  • Jeśli unikalne identyfikatory nie istnieją, Liquibase zastosuje changeset w bazie danych.
  • Jeśli unikalne identyfikatory istnieją, obliczana jest suma MD5Sum (suma kontrolna pliku przechowywana w kolumnie DATABASECHANGELOG.MD5SUM ) changesetu i porównywana z tą w bazie danych. Jeśli są różne, Liquibase wyświetli komunikat o błędzie. Więcej o obliczaniu sum kontrolnych przeczytasz tutaj

Jeśli dodasz to do istniejącego changesetu, zakończy się on niepowodzeniem:

Zrzut ekranu pokazujący Liquibase.

To jest w porządku:

Zrzut ekranu pokazujący Liquibase.

Jeśli jednak runOnChange jest ustawione na TRUE, Liquibase ponownie zastosuje changeset.

Pamiętaj, że ten parametr powinien być ustawiony na TRUE tylko dla obiektów, które można zastąpić (replace), takich jak widoki, paczki, procedury, funkcje itp.

Zrzut ekranu pokazujący Liquibase.

Wprowadzanie zmian w środowisku DEV przy użyciu Liquibase

Teraz zacznijmy wprowadzać i śledzić zmiany w naszej bazie danych. Aby zachować prostotę, określę wymagania i kroki, które należy wykonać, aby wdrożyć każde z nich.

Moje przykłady pokażą zmiany wprowadzone przez dwóch programistów, RAFAŁA oraz JANA, którzy pracują z tą samą bazą danych DEV . Korzystają oni również z GIT i Visual Studio Code.

ŻADNE ZMIANY nie są wprowadzane bezpośrednio w bazie danych. Wszystko musi przechodzić przez pliki SQL i Liquibase.

Jest to zasada pisana czerwoną czcionką, której muszą przestrzegać wszyscy programiści. W przeciwnym razie używanie Liquibase nie ma sensu.

Wymaganie JIRA-1 (przypisane do programisty: RAFAŁ)

  • Dodaj nową tabelę CUSTOMERS i klucz obcy (Foreign Key) do istniejącej tabeli COUNTRIES
  • W tym momencie aplikacja ma version_1
  • Numer zadania Jira to JIRA-1

Teraz przejdźmy przez niezbędne kroki.

Utwórz nowy branch GIT JIRA-1 na podstawie brancha DEV

Zrzut ekranu pokazujący Liquibase.

Utwórz tabelę

Kroki:

  • Utwórz nowy plik DATABASE/HR/TABLE/customers.sql
  • Dodaj składnię Liquibase i unikalne wartości changesetu – ID oraz autor (author)
  • Dodaj kod DDL

Zrzut ekranu pokazujący Liquibase.

Legenda:

  • rafal – authorId.
  • create_customers_table – changeset ID.
  • runOnChange:false – ten parametr jest opcjonalny, a domyślną wartością jest false (co oznacza, że nie trzeba go pisać). Changeset z runOnChange:false to typ zmiany, który można wykonać tylko raz. Więcej o tym parametrze przeczytasz tutaj
  • context – opcjonalny parametr służący do podania bardziej szczegółowych informacji o wykonywanych changesetach. Daje większą kontrolę nad zmianami. Wartość kontekstu powinna zostać zapisana w kolumnie DATABASECHANGELOG.CONTEXT. Więcej o kontekstach tutaj
  • labels – opcjonalny parametr, podobny do kontekstów, zapisywany w kolumnie DATABASECHANGELOG.LABELS. Więcej w dokumentacji Liquibase
--liquibase formatted sql
--changeset rafal:create_customers_table runOnChange:false context:version1 labels:JIRA-1
--comment New customers table
CREATE TABLE HR.CUSTOMERS
(

cust_id                  NUMBER         NOT NULL,
cust_first_name          VARCHAR2(20)   NOT NULL,
cust_last_name           VARCHAR2(40)   NOT NULL,
cust_gender              CHAR(1)        NOT NULL,
cust_year_of_birth       NUMBER(4)      NOT NULL,
cust_marital_status      VARCHAR2(20),
cust_street_address      VARCHAR2(40)   NOT NULL,
cust_postal_code         VARCHAR2(10)   NOT NULL,
cust_city                VARCHAR2(30)   NOT NULL,
cust_city_id             NUMBER         NOT NULL,
cust_state_province      VARCHAR2(40)   NOT NULL,
cust_state_province_id   NUMBER         NOT NULL,
country_id               CHAR(2)        NOT NULL,
cust_main_phone_number   VARCHAR2(25)   NOT NULL,
CONSTRAINT customers_pk
PRIMARY KEY (cust_id)
);

Utwórz Foreign Key

Kroki:

  • Utwórz nowy plik DATABASE/HR/FOREIGN_KEY/customers_country_fk.sql
  • Dodaj składnię Liquibase i unikalne wartości changesetu – ID oraz autor
  • Dodaj kod DDL

Zrzut ekranu pokazujący kod.

--liquibase formatted sql
--changeset rafal:customers_country_fk  context:version1 labels:JIRA-1
--comment Foreign key customers ->countries
alter table customers add CONSTRAINT customers_country_fk FOREIGN KEY (country_id) REFERENCES countries (country_id);

UPDATE-SQL

Dla jasności: obecnie ani tabela CUSTOMERS , ani foreign key nie istnieją w mojej bazie danych DEV . To tylko kod w moich plikach SQL. Muszę użyć polecenia Liquibase UPDATE wyjaśnionego wcześniej, aby wdrożyć zmiany.

Jednak przed wykonaniem polecenia UPDATE , wysoce zalecane jest najpierw uruchomienie polecenia UPDATE-SQL. Wygeneruje plik SQL, który pokaże, co zostałoby wykonane, gdybyś później uruchomił polecenie UPDATE .

liquibase --defaults-file=dev.liquibase.properties update-sql --label-filter=JIRA-1

Zrzut ekranu pokazujący Liquibase.

Legenda:

  • defaults-file – ten parametr służy do zdefiniowania mojego pliku połączenia
  • label-filter – opcjonalny parametr służący do wykonywania tylko zmian z określonymi etykietami. Jest to bardzo przydatne, zwłaszcza gdy nad tą samą bazą danych pracuje więcej niż jeden programista. Dlaczego powinieneś używać –label-filter?
    • Załóżmy, że programista RAFAŁ pracuje nad branchem GIT JIRA-1. W tym samym czasie programista JAN pracuje nad branchem GIT JIRA-2.
    • JAN wykonał już polecenie update ze swojego brancha JIRA-2, gdzie zmienił procedurę add_job_history_procedure.sql
    • Zaraz po JANIE, RAFAŁ wykona polecenie UPDATE bez określania –label-filter.
    • Co zostanie wdrożone na DEV? Wszystkie zmiany Rafała (tabela CUSTOMER + FK), a procedura add_job_history_procedure zostanie nadpisana wersją z brancha RAFAŁA JIRA-1. Stałoby się tak, ponieważ RAFAŁ nie ma jeszcze zmienionej przez JANA wersji procedury w swoim repozytorium.
    • Jeśli RAFAŁ użyje –labels-filter, wdrożone zostaną tylko jego zmiany.
  • DEV_PREVIEW.sql – to domyślna nazwa pliku output-file, którą zdefiniowałem w dev.liquibase.properties

Skrypt wygląda dobrze (pełny skrypt jest dostępny tutaj), więc jestem gotowy do wdrożenia moich zmian za pomocą polecenia UPDATE .

UPDATE

liquibase --defaults-file=dev.liquibase.properties update --label-filter=JIRA-1

Zrzut ekranu pokazujący Liquibase.

Ciekawa informacja w pliku DEV_PREVIEW.sql.

Zrzut ekranu pokazujący Liquibase.

I dwa nowe wiersze zostały wstawione do tabeli DATABASECHANGELOG:

Zrzut ekranu pokazujący Liquibase.

Są też dwie nowe kolumny:

Zrzut ekranu pokazujący Liquibase.

Zmerguj do brancha DEV

Moje zmiany dotyczące zadania JIRA-1 zostały pomyślnie wdrożone w bazie danych DEV . Mogę zmergować moje zmiany do gałęzi DEV .

Zrzut ekranu pokazujący Liquibase.

Wymaganie JIRA-2 (przypisane do programisty: JAN)

  • Utwórz nową paczkę (package) COE_DOM_HELPER
  • Zmień istniejące złączenia (joins) w EMP_DETAILS_VIEW ze staromodnych złączeń Oracle na złączenia ANSI
  • W tym momencie aplikacja ma wersję version_1
  • Numer zadania Jira to JIRA-2

Przejdźmy przez kroki.

Utwórz nową gałąź GIT JIRA-2

Zrzut ekranu pokazujący Liquibase.

Utwórz nową specyfikację i ciało paczki (package spec and body)

Kroki:

  • Najpierw utwórz dwa nowe foldery

Zrzut ekranu pokazujący Liquibase.

  • Uwzględnij te foldery w pliku master.xml

Zrzut ekranu pokazujący Liquibase.

Użyłem includeAll co oznacza, że wszystkie pliki SQL utworzone w tych folderach zostaną wykonane alfabetycznie. Jeśli chcesz mieć większą kontrolę, użyj tagu include file, tak jak zrobiłem to w linii powyżej (niebieska ramka).

  • Utwórz pliki z kodem, oddzielnie dla specyfikacji paczki i ciała paczki

Zrzut ekranu pokazujący Liquibase.

  • Dodaj składnię Liquibase do obu plików

Zrzut ekranu pokazujący Liquibase.

Linie do dodania do ciała paczki:

--liquibase formatted sql
--changeset john:COE_DOM_helper_body runOnChange:true endDelimiter:\n/ context:version1 labels:JIRA-2
--comment New COE_DOM_helper package body

Dodaj te linie do specyfikacji paczki:

--liquibase formatted sql
--changeset john:COE_DOM_helper_spec runOnChange:true endDelimiter:\n/ context:version1 labels:JIRA-2
--comment New COE_DOM_helper package spec

Legenda:

  • runOnChange – dla wszystkich obiektów, które są wymienialne (paczki, widoki, procedury), ten parametr powinien być ustawiony na true. Pozwala to na zmianę kodu w istniejącym changeset i ponowne uruchomienie go tyle razy, ile to konieczne.
  • endDelimiter – atrybut, który pozwala określić ogranicznik oddzielający surowe instrukcje SQL w changesetach. \n/ oznacza ogranicznik „/”

Zmień WIDOK (VIEW)

Kroki:

  • Zmień te wartości w changeset, przeprowadź refaktoryzację i zmień staromodne złączenia Oracle na złączenia ANSI
  • Changeset ma ustawione runOnChange:true, więc Liquibase przeliczy sumę kontrolną podczas wykonywania i ponownie uruchomi ten skrypt

Zrzut ekranu pokazujący Liquibase.

UPDATE-SQL

Podgląd tego, co zostanie wdrożone za pomocą tego polecenia:

liquibase --defaults-file=dev.liquibase.properties update-sql --label-filter=JIRA-2

Ekran pokazujący Liquibase.

Wygląda dobrze (podgląd całego pliku tutaj).

Zrzut ekranu pokazujący Liquibase.

UPDATE

Wykonaj polecenie Liquibase UPDATE, aby wdrożyć te 3 nowe zmiany:

liquibase --defaults-file=dev.liquibase.properties update --label-filter=JIRA-2

Zrzut ekranu pokazujący Liquibase.

Zmiany zostały wdrożone w mojej bazie danych DEV , a w tabeli DATABASECHANGELOG pojawiły się 3 nowe wiersze:

Zrzut ekranu pokazujący Liquibase.

Zmerguj do brancha DEV

Zrzut ekranu pokazujący Liquibase.

Wymaganie JIRA-3 (przypisane do programisty: RAFAŁ)

  • Utwórz changeset, który skompiluje nieprawidłowe obiekty schematu HR przed i po wykonaniu innych zmian w bazie danych
  • Utwórz nową tabelę PARAMETERS i wstaw wartości. Dane do wstawienia są inne dla środowisk DEV i PROD

Utwórz nową gałąź GIT JIRA-3

Wykonuj skrypty / bloki anonimowe za pomocą Liquibase (kompilacja schematu)

Kroki:

  • Aby uruchomić coś przed i po innych zmianach, utwórz foldery /pre-scripts/ oraz /post-scripts/

  • Uwzględnij nowe pliki w master.xml

Zrzut ekranu pokazujący Liquibase.

  • Pliki te zajmą się kolejnością Twoich pre- i post-skryptów. Na potrzeby tego przykładu nie chcę używać includeAll, ponieważ chcę mieć pełną kontrolę. Zamiast tego używam include file)

Zrzut ekranu pokazujący Liquibase.

  • Napisz skrypt, który skompiluje Twój schemat HR przed i po wykonaniu innych changesetów Liquibase
    • Dla PRE_SCRIPTS:

Zrzut ekranu pokazujący Liquibase.

  • Uwzględnij ten plik w pre_scripts_order.xml

Zrzut ekranu pokazujący Liquibase.

Pełny kod changesetu:

--liquibase formatted sql
--changeset rafal:compile_HR_after endDelimiter:\n/ context:version_1 labels:JIRA-3 runAlways:true
--comment Compile HR invalid objects after other changesets executuon
begin
dbms_utility.compile_schema(
schema         => 'HR',
compile_all    => false,
reuse_settings => true);
end;
/

W powyższej składni pojawia się coś nowego – runAlways:true. Dzięki temu parametrowi Liquibase wykona ten changeset za każdym razem, gdy uruchomisz polecenie UPDATE .

  • Powtórz powyższe kroki dla POST_SCRIPTS

Zrzut ekranu pokazujący Liquibase.

Zrzut ekranu pokazujący Liquibase.

Pełny kod changesetu:

--liquibase formatted sql
--changeset rafal:compile_HR_before endDelimiter:\n/ context:version_1 labels:JIRA-3 runAlways:true
--comment Compile HR invalid objects before other changesets executuon
begin
dbms_utility.compile_schema(
schema         => 'HR',
compile_all    => false,
reuse_settings => true);
end;
/

Utwórz nową tabelę PARAMETERS

Kroki:

  • Utwórz nowy plik DATABASE/HR/TABLE/parameters.sql i changeset

Zrzut ekranu pokazujący Liquibase.

--liquibase formatted sql
--changeset rafal:create_paramters_table runOnChange:false context:version1 labels:JIRA-3
--comment New parameters table
create table hr.parameters (
id       number generated by default on null as identity
constraint parameters_id_pk primary key,
name     varchar2(255 char),
value    varchar2(4000 char)
);

Użyj preConditions, aby wstawić wartości specyficzne dla środowiska DEV lub PROD

Kroki:

  • Utwórz nowy folder POST_SCRIPTS/DML
  • Kod DML powinien być wykonany na końcu, aby mieć pewność, że obiekt będzie istniał (tabela PARAMETERS zostanie utworzona wcześniej)

Zrzut ekranu pokazujący Liquibase.

  • Utwórz nowy changelog dml_order.xml , który posłuży do kontrolowania kolejności wykonywania DML. Ważne jest, aby starannie układać DML-e, ponieważ tabele mogą mieć zależności
  • Dodaj ścieżkę do dml_order.xml do pliku post_scripts_order.xml

Zrzut ekranu pokazujący Liquibase.

  • Utwórz nowy plik POST_SCRIPTS/DML/parameters_dml.sql. Ten plik będzie używany dla całego kodu DML wyłącznie dla tabeli PARAMETERS
  • Dodaj ścieżkę do parameters_dml.sql do changelogu dml_order.xml

Zrzut ekranu pokazujący Liquibase.

  • Utwórz kod DML, aby wstawić wartości do PARAMETERS. Kod ten powinien być wykonany wyłącznie w środowisku DEV

Zrzut ekranu pokazujący Liquibase.

  • Utwórz podobny kod do wstawienia wyłącznie na PROD

Jednak to nie wystarczy, ponieważ tak zdefiniowane changesety zostaną wykonane w każdym środowisku. Będziesz musiał użyć Liquibase preConditions.

Skąd będziesz wiedzieć, czy Twoja baza danych Autonomous to DEV czy PROD? Twój parametr service_name będzie zawierał wartość DEV lub PROD . To zapytanie powinno wystarczyć:

Zrzut ekranu pokazujący Liquibase.

  • Zmodyfikuj swoje changesety DML tak, aby były wykonywane tylko w środowiskach DEV lub PROD

Zrzut ekranu pokazujący Liquibase.

UPDATE-SQL

Zmiany są przygotowane. Uruchom UPDATE-SQL, aby sprawdzić, co zostanie wykonane na DEV:

liquibase --defaults-file=dev.liquibase.properties update-sql --label-filter=JIRA-3

Mój skrypt podglądu znajduje się poniżej oraz w repozytorium tutaj, i wszystko jest tak, jak oczekiwałem. Co się wydarzy:

  • Schemat HR zostanie skompilowany
  • Tabela PARAMETERS zostanie utworzona
  • Wartości do PARAMETERS zostaną wstawione, ale tylko te dla środowiska DEV
  • Dla wartości PROD , jeden wiersz zostanie wstawiony do tabeli DATABASECHANGELOG z wartością w kolumnie EXECTYPE = MARK_RAN
  • Schemat HR zostanie skompilowany

Skrypt podglądu:

-- Lock Database
UPDATE HR.DATABASECHANGELOGLOCK SET LOCKED = 1, LOCKEDBY = 'localhost (192.168.0.2)', LOCKGRANTED = SYSTIMESTAMP WHERE ID = 1 AND LOCKED = 0;

-- *********************************************************************
-- Update Database Script
-- *********************************************************************
-- Change Log: master.xml
-- Ran at: 22.02.2024, 15:08
-- Against: HR@jdbc:oracle:thin:@dev_low
-- Liquibase version: 4.25.1
-- *********************************************************************

-- Changeset PRE_SCRIPTS/compile_HR_before.sql::compile_HR_after::rafal
-- Compile HR invalid objects after other changesets executuon
begin
dbms_utility.compile_schema(
schema         => 'HR',
compile_all    => false,
reuse_settings => true);
end;
/

INSERT INTO HR.DATABASECHANGELOG (ID, AUTHOR, FILENAME, DATEEXECUTED, ORDEREXECUTED, MD5SUM, DESCRIPTION, COMMENTS, EXECTYPE, CONTEXTS, LABELS, LIQUIBASE, DEPLOYMENT_ID) VALUES ('compile_HR_after', 'rafal', 'PRE_SCRIPTS/compile_HR_before.sql', SYSTIMESTAMP, 50, '9:84b226d042023ca9771041f4c887fd6a', 'sql', 'Compile HR invalid objects after other changesets executuon', 'EXECUTED', 'version_1', 'jira-3', '4.25.1', '8610923542');

-- Changeset DATABASE/HR/TABLE/parameters.sql::create_paramters_table::rafal
-- New parameters table
create table hr.parameters (
id       number generated by default on null as identity
constraint parameters_id_pk primary key,
name     varchar2(255 char),
value    varchar2(4000 char)
);

INSERT INTO HR.DATABASECHANGELOG (ID, AUTHOR, FILENAME, DATEEXECUTED, ORDEREXECUTED, MD5SUM, DESCRIPTION, COMMENTS, EXECTYPE, CONTEXTS, LABELS, LIQUIBASE, DEPLOYMENT_ID) VALUES ('create_paramters_table', 'rafal', 'DATABASE/HR/TABLE/parameters.sql', SYSTIMESTAMP, 51, '9:830a9f31b55e62c8fc4a3f8c2ee4e51c', 'sql', 'New parameters table', 'EXECUTED', 'version1', 'jira-3', '4.25.1', '8610923542');

-- Changeset POST_SCRIPTS/DML/parameters_dml.sql::DEV_parameters_env_type::rafal
-- Environment type values for PARAMETERS table at DEV only
INSERT INTO HR.PARAMETERS (name, value) VALUES ('ENVIRONMENT_TYPE', 'DEV');

INSERT INTO HR.DATABASECHANGELOG (ID, AUTHOR, FILENAME, DATEEXECUTED, ORDEREXECUTED, MD5SUM, DESCRIPTION, COMMENTS, EXECTYPE, CONTEXTS, LABELS, LIQUIBASE, DEPLOYMENT_ID) VALUES ('DEV_parameters_env_type', 'rafal', 'POST_SCRIPTS/DML/parameters_dml.sql', SYSTIMESTAMP, 52, '9:d707b31273b18adf3fce32ddce9f1553', 'sql', 'Environment type values for PARAMETERS table at DEV only', 'EXECUTED', 'version_1', 'jira-3', '4.25.1', '8610923542');

-- Changeset POST_SCRIPTS/DML/parameters_dml.sql::PROD_parameters_env_type::rafal
-- Environment type values for PARAMETERS table at PROD only
INSERT INTO HR.DATABASECHANGELOG (ID, AUTHOR, FILENAME, DATEEXECUTED, ORDEREXECUTED, MD5SUM, DESCRIPTION, COMMENTS, EXECTYPE, CONTEXTS, LABELS, LIQUIBASE, DEPLOYMENT_ID) VALUES ('PROD_parameters_env_type', 'rafal', 'POST_SCRIPTS/DML/parameters_dml.sql', SYSTIMESTAMP, 53, '9:7868f1d9e91fa2c43b86cd6f8bd5d698', 'sql', 'Environment type values for PARAMETERS table at PROD only', 'MARK_RAN', 'version_1', 'jira-3', '4.25.1', '8610923542');

-- Changeset POST_SCRIPTS/compile_HR_after.sql::compile_HR_before::rafal
-- Compile HR invalid objects before other changesets executuon
begin
dbms_utility.compile_schema(
schema         => 'HR',
compile_all    => false,
reuse_settings => true);
end;
/

INSERT INTO HR.DATABASECHANGELOG (ID, AUTHOR, FILENAME, DATEEXECUTED, ORDEREXECUTED, MD5SUM, DESCRIPTION, COMMENTS, EXECTYPE, CONTEXTS, LABELS, LIQUIBASE, DEPLOYMENT_ID) VALUES ('compile_HR_before', 'rafal', 'POST_SCRIPTS/compile_HR_after.sql', SYSTIMESTAMP, 54, '9:84b226d042023ca9771041f4c887fd6a', 'sql', 'Compile HR invalid objects before other changesets executuon', 'EXECUTED', 'version_1', 'jira-3', '4.25.1', '8610923542');

-- Release Database Lock
UPDATE HR.DATABASECHANGELOGLOCK SET LOCKED = 0, LOCKEDBY = NULL, LOCKGRANTED = NULL WHERE ID = 1;

Wykonaj zmiany na DEV

liquibase --defaults-file=dev.liquibase.properties update --label-filter=JIRA-3

Wszystko poszło dobrze.

Zrzut ekranu pokazujący Liquibase.

Zrzut ekranu pokazujący Liquibase.

W tabeli PARAMETERS znajdują się tylko wartości dla DEV :

Zrzut ekranu pokazujący Liquibase.

Możesz teraz zmergować gałąź JIRA-3 do DEV.

Wdrożenie na PROD

Na koniec pokażę Ci wdrażanie zmian dokonanych na DEV do innego środowiska – w moim przypadku jest to PROD, ale może to być również UAT, PRE-PROD lub dowolne inne. Najpierw przeniosę zmiany z JIRA-1 i JIRA-2, a następnie z JIRA-3. Będziesz musiał jedynie przygotować odpowiednie pliki liquibase.properties z połączeniami.

Wdróż zmiany z JIRA-1 i JIRA-2 na PROD

W poprzedniej części tego poradnika RAFAŁ i JAN opracowali kilka nowych funkcji dla wersji version_1 swojej aplikacji. Ukończyli zadania JIRA-1, JIRA-2 i JIRA-3.

Do naszego zespołu dołącza nowa osoba: Matt, kierownik projektu. Mówi: „Musimy wdrożyć na PROD tylko zmiany z zadań JIRA-1 i JIRA-2”.

Cieszę się, że użyliśmy kontekstów i etykiet, ponieważ będzie to łatwiejsze. Oto jak to zrobić.

Branchowanie GIT i przełączanie

Jak pamiętasz, zmergowaliśmy zadania JIRA-1, JIRA-2 i JIRA-3 do brancha DEV . Nie mogę więc po prostu zmergować DEV do PROD w celu wdrożenia, ponieważ obejmowałoby to zmiany JIRA-3, które nie są wymagane.

Zrzut ekranu pokazujący Liquibase.

Oto co musimy zrobić:

  • Utwórz dodatkową gałąź i nazwij ją release_1.

Zrzut ekranu pokazujący Liquibase.

  • Następnie zmerguj tylko gałęzie JIRA-1 i JIRA-2 do nowo utworzonej gałęzi release_1

Zrzut ekranu pokazujący Liquibase.

Jesteś prawie gotowy do wdrożenia na PROD.

  • Zmerguj branch release_1 do swojego brancha PROD

Zrzut ekranu pokazujący Liquibase.

UPDATE-SQL

Teraz wdróż zmiany ze swojego brancha PROD do swojej bazy danych PROD . Uruchom update-sql , aby zobaczyć, co zostanie wdrożone:

liquibase --defaults-file=prod.liquibase.properties update-sql --label-filter=JIRA-1,JIRA-2

Na branchu PROD nie ma innych oczekujących zmian, więc możesz również uruchomić to polecenie bez parametru –label-filter.

Zrzut ekranu pokazujący Liquibase.

Skrypt wygląda zgodnie z oczekiwaniami i zawiera tylko zmiany z zadań JIRA-1 i JIRA-2 (podgląd pełnego skryptu tutaj).

Zrzut ekranu pokazujący Liquibase.

POLECENIE LIQUIBASE STATUS

Możesz również użyć polecenia status , aby sprawdzić, które changesety zostaną wdrożone:

liquibase --defaults-file=prod.liquibase.properties status

Wynik wygląda następująco:

5 changesets have not been applied to HR@jdbc:oracle:thin:@prod_low
DATABASE/HR/TABLE/customers.sql::create_customers_table::rafal
DATABASE/HR/VIEW/emp_details_view_view.sql::emp_details_view_view::john
DATABASE/HR/REF_CONSTRAINT/customers_country_fk.sql::customers_country_fk::rafal
DATABASE/HR/PACKAGE_SPEC/COE_DOM_helper.sql::COE_DOM_helper_spec::john
DATABASE/HR/PACKAGE_BODY/COE_DOM_helper.sql::COE_DOM_helper_body::john

UPDATE

Kroki:

  • Wykonaj zmiany w bazie danych PROD
liquibase --defaults-file=prod.liquibase.properties update --label-filter=JIRA-1,JIRA-2

Zrzut ekranu pokazujący Liquibase.

  • Sprawdź tabelę DATABASECHANGELOG w bazie danych PROD

Zrzut ekranu pokazujący Liquibase.

Wszystko zostało wdrożone zgodnie z oczekiwaniami.

Wdróż zmiany z JIRA-3 na PROD

Czas wdrożyć pozostałe zmiany z JIRA-3 na PROD.

Ponownie trochę branchowania GIT

Aby to zrobić, musisz zmergować JIRA-3 do nowo utworzonego brancha release_2. Następnie zmerguj branch release_2 do PROD (powtórz kroki wymienione powyżej tam, gdzie ma to zastosowanie).

Zrzut ekranu pokazujący Liquibase.

Zrzut ekranu pokazujący Liquibase.

Zrzut ekranu pokazujący Liquibase.

UPDATE-SQL

Kroki:

  • Będąc na branchu GIT PROD , podejrzyj, co zostanie wykonane w bazie danych PROD :
liquibase --defaults-file=prod.liquibase.properties update-sql --label-filter=JIRA-3

Plik wygląda dobrze (pełny podgląd skryptu jest dostępny tutaj).

Zrzut ekranu pokazujący Liquibase.

UPDATE

Kroki:

  • Wykonaj zmiany z zadania JIRA-3 w bazie danych PROD :
liquibase --defaults-file=prod.liquibase.properties update --label-filter=JIRA-3

Zrzut ekranu pokazujący Liquibase.

  • Sprawdź tabelę DATABASECHANGELOG :

Zrzut ekranu pokazujący Liquibase.

Ostatecznie wszystkie zmiany z zadań JIRA-1, JIRA-2 oraz JIRA-3 zostały wdrożone na PROD. Aby sprawdzić, czy to prawda, ponownie uruchom polecenie STATUS :

liquibase --defaults-file=prod.liquibase.properties status

Zrzut ekranu pokazujący Liquibase.

Wynik wygląda następująco:

2 changesets have not been applied to HR@jdbc:oracle:thin:@prod_low
PRE_SCRIPTS/compile_HR_before.sql::compile_HR_after::rafal
POST_SCRIPTS/compile_HR_after.sql::compile_HR_before::rafal

Jest to prawdą, ponieważ są to dwa changesety, które mają ustawiony parametr runAlways:true , więc będą one wykonywane za każdym razem.

Poradnik Liquibase: Podsumowanie

To, co przeczytałeś powyżej, to najlepsze praktyki, których nauczyłem się podczas ostatnich kilku lat pracy z Liquibase – w wielu projektach i dla różnych klientów. Mam nadzieję, że da Ci to pewien wgląd w możliwości tego darmowego narzędzia open-source. Oto kilka zaleceń dotyczących korzystania z tego rozwiązania:

  • Przed uruchomieniem polecenia UPDATE zawsze najpierw używaj UPDATE-SQL, aby upewnić się, że kod, który zostanie wykonany, jest poprawny
  • Nigdy nie uruchamiaj ręcznie kodu wygenerowanego za pomocą UPDATE-SQL. Do wprowadzania zmian używaj polecenia UPDATE
  • Upewnij się, że wszyscy programiści z Twojego zespołu używają Liquibase i nikt nie wprowadza tajnych zmian bezpośrednio w bazie danych
  • Używaj kontekstów i etykiet (labels)
  • Używaj komentarzy do opisywania swoich zmian
  • Stosuj metodę „roll forward” zamiast robienia rollbacków. Wiem, że ta rada będzie miała wielu przeciwników i zwolenników, prawdopodobnie również w Twoim zespole projektowym, więc aby przygotować się do nadchodzącej dyskusji, możesz przeczytać o rollbackach Liquibase w dokumentacji Liquibase oraz w świetnym artykule mojego kolegi Łukasza Kosiciarza – Liquibase rollback: A smart way to do it with Jenkins

Możesz również zapoznać się z innymi artykułami związanymi z Liquibase na blogu Pretius:

  1. SQLcl Liquibase tags: Learn to use them effectively with a simple guide
  2. Track your DEV database changes and export them to UAT using SQLcl Liquibase
  3. Use SQLcl Liquibase to move all database objects from DEV to the UAT environment
  4. Use Liquibase to track DB changes without direct access– A quick guide
  5. Testcontainers + Liquibase: Make integration testing easier
  6. Boost the management of your Oracle Database version control changes with Liquibase

Potrzebujesz ekspertów od baz danych?

Programiści Pretius doskonale wiedzą, jak efektywnie korzystać z Liquibase. Mamy ogromne doświadczenie w pracy z różnymi branżami i wiemy dużo o projektowaniu architektury systemów. Czy potrzebujesz pomocy w tworzeniu lub odświeżaniu złożonego rozwiązania z wieloma bazami danych? Napisz do nas na hello@pretius.com (lub skorzystaj z poniższego formularza kontaktowego). Odezwiemy się w ciągu 48 godzin i wspólnie ustalimy, co możemy zrobić dla Twojej firmy.

Szukasz firmy tworzącej oprogramowanie?

Pracuj z zespołem, który pomógł już dziesiątkom rynkowych liderów. Umów spotkanie, by dowiedzieć się:

  • Jak działają nasze produkty
  • Jak możesz oszczędzić czas i pieniądze
  • Czym nasze rozwiązania różnią się od konkurencji

Przebieg kontaktu z Pretius

Dbamy o bezpieczeństwo Twoich danych: Certyfikat ISO

Działamy zgodnie z normą ISO 27001, zapewniając najwyższy poziom bezpieczeństwa Twoich danych.
certified dekra 27001
© 2026 Pretius. All right reserved.