1. Wstęp do Atlas

atlas

Atlas to narzędzie niezależne od języka, zaprojektowane specjalnie do zarządzania i migracji schematów baz danych przy użyciu nowoczesnych zasad DevOps. Zapewnia dwie opcje pracy:

  • Deklaratywna: Podobnie jak w przypadku Terraforma, Atlas porównuje bieżący stan bazy danych z pożądanym stanem zdefiniowanym za pomocą HCL, SQL lub schematu ORM. Na podstawie tego porównania generuje i wykonuje plan migracji w celu przejścia bazy danych do pożądanego stanu.
  • Zwersjonowana: W przeciwieństwie do innych narzędzi, Atlas automatycznie planuje migracje schematu dla Ciebie. Użytkownicy mogą opisać swój pożądany schemat bazy danych za pomocą HCL, SQL lub wybranego przez nich ORM, a dzięki Atlasowi zaplanować, przejrzeć i zastosować niezbędne migracje do bazy danych.

Główną zaletą Atlasa jest uproszczenie złożoności zarządzania bazami danych, co ułatwia kontrolę wersji, współpracę i wdrożenia.

2. Instalacja Atlasa

Przed rozpoczęciem zarządzania wersjami baz danych za pomocą Atlasa, musimy go zainstalować. Poniżej znajdują się kroki instalacji dla różnych platform.

2.1 Instalacja na macOS + Linux

Na systemach macOS lub Linux możesz pobrać i zainstalować najnowszą wersję Atlasa za pomocą poniższego polecenia w wierszu poleceń:

curl -sSf https://atlasgo.sh | sh

To polecenie automatycznie wykryje wersję systemu operacyjnego, pobierze odpowiednią wersję kompilacji i umieści plik binarny Atlasa w ścieżce wykonywalnej.

2.2 Instalacja za pomocą Homebrew

Jeśli używasz macOS i masz już zainstalowany menedżer pakietów Homebrew, instalacja Atlasa jest tak prosta jak wykonanie polecenia:

brew install ariga/tap/atlas

To spowoduje pobranie najnowszej wersji Atlasa z repozytorium Homebrew i zainstaluje go.

2.3 Instalacja przy użyciu Dockera

Instalowanie i uruchamianie Atlasa za pomocą Dockera jest szybkim i wygodnym sposobem, zwłaszcza do tymczasowego testowania lub dla użytkowników preferujących nie instalowanie dodatkowego oprogramowania na swoim systemie gospodarza.

Najpierw pobierz obraz Docker Atlasa:

docker pull arigaio/atlas

Następnie możesz uruchomić polecenie pomocy, aby potwierdzić udaną instalację:

docker run --rm arigaio/atlas --help

Jeśli kontener potrzebuje dostępu do sieci gospodarza lub katalogów lokalnych, użyj flagi --net=host i zamontuj wymagane katalogi:

docker run --rm --net=host \
  -v $(pwd)/migrations:/migrations \
  arigaio/atlas migrate apply \
  --url "mysql://root:pass@:3306/test"

2.4 Instalacja na Windows

Pobierz plik binarny https://release.ariga.io/atlas/atlas-windows-amd64-latest.exe i dodaj ścieżkę instalacji do zmiennej środowiskowej PATH systemu.

3. Eksportowanie Istniejącej Struktury Tabeli Bazy Danych Za Pomocą Atlas

Atlas udostępnia polecenie atlas schema inspect, które można użyć do eksportowania struktury istniejącej bazy danych. To polecenie obsługuje odczytywanie opisów bazy danych z adresu URL bazy danych i wyprowadza je w trzech różnych formatach: domyślnym formacie Atlas HCL, formacie SQL i formacie JSON. W tym przewodniku pokażemy, jak korzystać z formatów Atlas HCL i SQL, ponieważ format JSON jest zazwyczaj używany do przetwarzania danych wyjściowych za pomocą jq.

Aby sprawdzić lokalnie uruchomioną instancję MySQL i zapisać wynik do pliku o nazwie schema.hcl, użyj następującego polecenia:

atlas schema inspect -u "mysql://root:pass@localhost:3306/example" > schema.hcl

Otwórz plik schema.hcl, aby zobaczyć definicję struktury tabeli Atlas opisującą bazę danych (HCL to format konfiguracji struktury niezależnej od bazy danych, zdefiniowany przez Atlas). Na przykład ten plik będzie zawierał następującą zawartość:

table "users" {
  schema = schema.example
  column "id" {
    null = false
    type = int
  }
  column "name" {
    null = true
    type = varchar(100)
  }
  primary_key {
    columns = [column.id]
  }
}

Ten blok kodu reprezentuje strukturę tabeli z kolumnami id i name. Pole schema odnosi się do definicji modelu example zdefiniowanej gdzie indziej w dokumencie. Dodatkowo, podblok primary_key określa kolumnę id jako klucz główny dla tabeli. Atlas stara się naśladować składnię bazy danych, na którą wpływa. W tym przykładzie kolumna id ma typ int, a kolumna name ma typ varchar(100).

Podobnie, aby wyeksportować definicję modelu SQL bazy danych, można użyć następującego polecenia:

atlas schema inspect -u "mysql://root:pass@localhost:3306/example" --format '{{ sql . }}' > schema.sql

Otwórz plik schema.sql, aby zobaczyć opis SQL bazy danych, zazwyczaj zawierający niektóre instrukcje CREATE TABLE.

To podejście ułatwia zrozumienie szczegółów istniejącej struktury tabeli bazy danych i dostarcza dokładne odniesienie do kolejnych zwersjonowanych migracji.

4.1 Deklaratywny Workflow

Deklaratywny Workflow Atlas pozwala użytkownikom zdeklarować pożądany stan końcowy bazy danych. Użytkownicy muszą tylko opisać, jaki stan końcowy schematu bazy danych chcą osiągnąć, a narzędzie Atlas automatycznie wygeneruje i wykonuje plany migracji, aby bezpiecznie przejść ze stanu bieżącego bazy danych do tego oczekiwanego stanu.

Poniżej przedstawiono, jak użyć Deklaratywnego Workflow, by zdefiniować i osiągnąć pożądany stan bazy danych:

4.1.1 Definiowanie Struktury Docelowej Tabeli

Po pierwsze, należy utworzyć plik definiujący oczekiwaną strukturę bazy danych, która może być w formacie HCL, SQL lub ORM (Mapowanie Obiektowo-Relacyjne).

Przyjmując format HCL jako przykład, zdefiniuj nową tabelę blog_posts:

table "blog_posts" {
  schema = schema.example
  column "id" {
    null = false
    type = int
  }
  column "title" {
    null = true
    type = varchar(100)
  }
  column "body" {
    null = true
    type = text
  }
  column "author_id" {
    null = true
    type = int
  }
  primary_key {
    columns = [column.id]
  }
  foreign_key "author_fk" {
    columns     = [column.author_id]
    ref_columns = [table.users.column.id]
  }
}

Wskazówka: Składnia formatu HCL zostanie omówiona w późniejszej sekcji.

4.1.2 Wykonywanie Migracji za Pomocą Narzędzia Atlas

Po zdefiniowaniu struktury tabeli bazy danych, można użyć polecenia schema apply Atlas do wykonania migracji.

atlas schema apply \
  -u "mysql://root:pass@localhost:3306/example" \
  --to file://schema.hcl

Po wykonaniu powyższego polecenia, Atlas porówna istniejącą strukturę bazy danych z zdefiniowaną w pliku schemą, wygeneruje plan migracji i poprosi użytkownika o potwierdzenie wykonania. Po potwierdzeniu planu wykonania, Atlas przeprowadzi migrację na bazie danych i zaktualizuje ją do pożądanego stanu.

4.2 Workflow Wersjonowany

Workflow Wersjonowany to inny tryb użycia obsługiwany przez Atlas, czasem nazywany "migracją opartą na zmianach". Jest odpowiedni dla scenariuszy, w których zmiany schematu bazy danych muszą być kontrolowane wersjonowano i podlegać recenzji w procesie przeglądu kodu.

Kroki Workflow Wersjonowanego obejmują:

4.2.1 Obliczanie różnic

Przed rozpoczęciem migracji konieczne jest porównanie bieżącej struktury bazy danych z pożądanym stanem i określenie różnic między nimi. Można to osiągnąć, wykonując polecenie atlas migrate diff.

atlas migrate diff create_blog_posts \
  --dir "file://migrations" \
  --to "file://schema.hcl" \
  --dev-url "docker://mysql/8/example"

Parametr --dir określa adres URL folderu migracji, domyślnie ustawiony na file://migrations. Parametr --to określa adres URL pożądanego stanu (np. baza danych środowiska deweloperskiego), a --dev-url dostarcza adres URL bazy danych deweloperskiej użytej do obliczenia różnic (zauważ, że --dev-url musi wskazywać na pustą bazę danych, którą Atlas używa do obliczania różnic).

Wskazówka: Jeśli chcesz wygenerować pliki SQL, odwołaj się do poprzedniego punktu w celu określenia formatu za pomocą parametru --format.

4.2.2 Zastosowanie zmian migracyjnych

Po zakończeniu obliczania różnic, Atlas wygeneruje dwa pliki migracyjne zapisane w folderze migrations. Na przykład, jeśli wybrany format to SQL, pliki wygenerowane przez polecenie diff, takie jak poniższy plik SQL, zawierają polecenia migracyjne do utworzenia nowej tabeli:

-- utwórz tabelę "blog_posts"
CREATE TABLE `blog_posts` (
  `id` int NOT NULL,
  `title` varchar(100) DEFAULT NULL,
  `body` text DEFAULT NULL,
  `author_id` int NULL REFERENCES `users`(id),
  PRIMARY KEY (`id`)
);

Po wygenerowaniu plików migracyjnych można użyć narzędzi kontroli wersji (np. Gita) do zarządzania tymi zmianami. Ten podejście pozwala na dokonywanie licznych modyfikacji struktury tabel w bazie danych środowisku deweloperskim, a gdy nadejdzie czas wydania, porównanie środowiska deweloperskiego i środowiska UAT za pomocą poleceń Atlas do wygenerowania plików migracyjnych struktury tabel bazy danych. Następnie te pliki migracyjne można zastosować do środowisk UAT i produkcyjnego w celu aktualizacji bazy danych.

Te dwa przepływy pracy, Deklaratywny i Zwersjonowany, zapewniają elastyczność dla różnych trybów rozwoju i wdrożeń, pozwalając zespołom wybrać metodę, która najlepiej odpowiada potrzebom ich projektu dotyczącym zarządzania zmianami schematu bazy danych.

5. Opis formatu HCL

5.1 Wprowadzenie

HCL to deklaratywny język używany do opisywania definicji struktury tabel bazy danych. Atlas używa formatu HCL do zapisywania schem baz danych, zapewniając bogatą strukturę do opisywania różnych aspektów bazy danych. Zaletą HCL jest jego czytelność, łatwość utrzymania i obsługa funkcji takich jak wstrzykiwanie zmiennych i dodatkowe adnotacje.

Wskazówka: Jeśli twój projekt musi się dostosować do wielu baz danych, opisanie struktur tabel w sposób niezależny od bazy danych za pomocą HCL może być bardzo wygodne.

5.2 Obiekt schema

Obiekt schema służy do opisu schematu bazy danych. W MySQL i SQLite reprezentuje DATABASE, podczas gdy w PostgreSQL reprezentuje SCHEMA. Plik HCL może zawierać jeden lub więcej obiektów schema.

schema "public" {
  comment = "Komentarz schematu"
}

schema "private" {}

5.3 Obiekt table

Obiekt table służy do opisu tabeli w bazie danych SQL, zawierając kolumny, indeksy, ograniczenia oraz różne dodatkowe właściwości obsługiwane przez różne sterowniki baz danych.

table "users" {
  schema = schema.public
  column "id" {
    type = int
  }
  column "name" {
    type = varchar(255)
  }
  column "manager_id" {
    type = int
  }
  primary_key {
    columns = [
      column.id
    ]
  }
  index "idx_name" {
    columns = [
      column.name
    ]
    unique = true
  }
  foreign_key "manager_fk" {
    columns     = [column.manager_id]
    ref_columns = [table.users.column.id]
    on_delete   = CASCADE
    on_update   = NO_ACTION
  }
}

5.4 Obiekt column

Obiekt column jest pod-zasobem table używanym do definiowania kolumn w tabeli.

column "name" {
  type = text
  null = false
}

column "age" {
  type = integer
  default = 42
}

column "active" {
  type = tinyint(1)
  default = true
}

5.5 Obiekt primary_key

Obiekt primary_key jest pod-zasobem table, który definiuje klucz główny tabeli.

primary_key {
  columns = [column.id]
}

5.6 Obiekt foreign_key

Obiekt foreign_key jest pod-zasobem table, który definiuje kolumny odwołujące się do kolumn w innych tabelach.

table "orders" {
  schema = schema.market
  // ...
  column "owner_id" {
    type = integer
  }
  foreign_key "owner_id" {
    columns     = [column.owner_id]
    ref_columns = [table.users.column.id]
    on_update   = NO_ACTION
    on_delete   = NO_ACTION
  }
}

5.7 Obiekt index

Obiekt index reprezentuje indeks w tabeli.

index "idx_name" {
  columns = [
    column.name
  ]
  unique = true
}