Powrót do strony głównej

Migracje baz danych w legacy bez ORM: struktura i praktyka

Artykuł opisuje podejście do migracji baz danych w systemach legacy bez ORM: struktura repozytorium Git z typami skryptów, tabele stanu per schema, procesy deploy w dev/prod/UAT. Zapewnia kontrolę, audyt i non-breaking zmiany.

Migracje baz danych: podejście legacy bez ORM i magii
Advertisement 728x90

System migracji baz danych dla projektów legacy bez ORM

W starszych systemach bez ORM migracje skryptów DDL/DML wymagają ścisłej kontroli. Proponowane podejście organizuje repozytorium i tabele stanu dla sekwencyjnego stosowania zmian w środowiskach testowych i produkcyjnych. Zapewnia to śledzenie, wsparcie danych i przewidywalność wdrożeń na relacyjnych bazach danych z ACID.

Podejście minimalizuje boilerplate w skryptach, automatyzuje weryfikację i logowanie. Skrypty dzielą się na typy: inicjalizacja, baseline, wersjonowane i powtarzalne. Każdy typ stosowany jest według reguł, eliminując duplikaty i zapewniając monotoniczność wersji.

Struktura repozytorium Git

Skrypty grupuje się według typów i stosuje w stałej kolejności:

Google AdInline article slot
  • Inicjalizacja środowiska — jednokrotnie dla tworzenia użytkowników, ról, baz danych i schematów. Zależy od środowiska (test/prod), wykonywane za pomocą psql.
  • Baseline — jednokrotnie na pustym schemacie dla początkowej wersji z prod i tabel kontrolnych.
  • Wersjonowane — sekwencyjnie według rosnących wersji (integer), tylko raz, w transakcji z logiem czasu i użytkownika.
  • Powtarzalne — przy zmianie SHA256 lub braku rekordu, po wersjonowanych, dla widoków/procedur/triggerów bez modyfikowalnych danych.

Typy obiektów:

  • Inicjalizacja: użytkownicy, role, bazy danych, schematy.
  • Baseline: tabele, dane, widoki, procedury, triggery.
  • Wersjonowane: zmiany schematu, migracje danych.
  • Powtarzalne: widoki, procedury, triggery.

Ta struktura inspirowana jest Flyway, ale dostosowana do ręcznych procesów bez zewnętrznych narzędzi.

Tabele stanu w schemacie

W każdym schemacie tworzone są tabele pomocnicze do śledzenia:

Google AdInline article slot
  • dbmigration_versions (version_id, is_baseline, created_at, created_by, created_from) — historia skryptów baseline i wersjonowanych.
  • dbmigration_repeatable (sha256sum, relative_path, created_at, created_by, created_from) — historia powtarzalnych, pozwala na ponowne zastosowanie przy zmianach.

Tabele zapewniają weryfikację przed zastosowaniem: skrypt jest wykonywany, jeśli rekordu brak lub checksum się zmienił. Logi obejmują użytkownika i timestamp dla audytu.

Wdrażanie w środowisku deweloperskim

W CI/CD (GitLab pipeline) klonuje się gałąź ze zmianami, następnie dla każdego schematu:

$ git clone <url zawierający zmiany w schematach baz danych>
$ USER_PASSWORD=topsecret123 dbmigration.py update --host <host> --port <port> --dbname <db> --user <user_name> schema1 ./db/schema1
$ USER_PASSWORD=topsecret123 dbmigration.py update --host <host> --port <port> --dbname <db> --user <user_name> schema2 ./db/schema2

To automatycznie stosuje oczekujące skrypty, zachowując dane.

Google AdInline article slot

Proces w produkcji

Obsługiwane jest hot deployment bez przestojów. Wcześniej testowane jest w UAT z testami smoke.

Kroki:

  • Rozpakować archiwum: tar xzvf system-x.y.z.tar.gz.
  • Dla schematu: cd system-x.y.z/schema1.
  • Wygenerować skrypt migracyjny: USER_PASSWORD=topsecret123 dbmigration.py verify --host <host> --port <port> --dbname <db> --user <user_name> --build-update-script ./schema1_migrate.sql schema1 ./db/schema1.
  • Przegląd schema1_migrate.sql pod kątem breaking changes.
  • Zastosować: PGPASSWORD=topsecret123 psql -h <host> -p <port> -U <user> -d <database> -v schema_name=<schema1> -f "schema1_migrate.sql".

Powtórzyć dla schematów. Tryb verify pozwala na podgląd bez zmian.

Kluczowe praktyki

  • Fix forward: zamiast rollback, nowa migracja naprawia błędy, zachowując dane.
  • Non-breaking changes: dodawać tabele/pola, usuwać po wydaniu, gdy nie są używane. Pozwala na równoległą pracę wersji na jednej bazie danych.
  • Śledzenie na poziomie schematu: wersje per schema, nie per DB.
  • Wstępna weryfikacja: generacja skryptów do przeglądu.
  • Zachowanie danych: przyrostowe aktualizacje bez drop/recreate.

Co jest ważne

  • Zautomatyzowane śledzenie eliminuje ręczny boilerplate i błędy w skryptach.
  • Monotoniczne wersje z transakcjami zapewniają spójność stanów.
  • Wsparcie hotfix dla różnych wersji (prod/UAT/dev) przez skrypty wersjonowane.
  • Audyt przez tabele: kto/kiedy/co zastosował.
  • Niezależność od RDBMS dla baz danych zgodnych z ACID.

— Editorial Team

Advertisement 728x90

Czytaj dalej