1. Einführung in Atlas
Atlas ist ein sprachunabhängiges Tool, das speziell für das Management und die Migration von Datenbankschemata unter Verwendung moderner DevOps-Prinzipien entwickelt wurde. Es bietet zwei Workflow-Optionen:
- Deklarativ: Ähnlich wie Terraform vergleicht Atlas den aktuellen Zustand der Datenbank mit dem gewünschten Zustand, der unter Verwendung von HCL, SQL oder ORM-Schema definiert ist. Basierend auf diesem Vergleich generiert und führt es einen Migrationsplan aus, um die Datenbank in ihren gewünschten Zustand zu überführen.
- Versioniert: Im Gegensatz zu anderen Tools plant Atlas automatisch die Schema-Migrationen für Sie. Benutzer können ihr gewünschtes Datenbankschema mit HCL, SQL oder ihrem gewählten ORM beschreiben und mit Atlas die erforderlichen Migrationen planen, überprüfen und anwenden.
Ein wesentlicher Vorteil von Atlas ist die Vereinfachung der Komplexität des Datenbankmanagements, sodass eine einfache Versionskontrolle, Zusammenarbeit und Implementierung möglich sind.
2. Atlas installieren
Bevor Sie Atlas zur Verwaltung von Datenbankversionen verwenden können, müssen Sie es installieren. Nachfolgend finden Sie die Installationsanweisungen für verschiedene Plattformen.
2.1 Installation auf macOS und Linux
Auf macOS- oder Linux-Systemen können Sie die neueste Version von Atlas mithilfe des folgenden Befehls herunterladen und installieren:
curl -sSf https://atlasgo.sh | sh
Dieser Befehl erkennt automatisch die Betriebssystemversion, lädt die geeignete Build-Version herunter und platziert die Atlas-Binärdatei im ausführbaren Pfad.
2.2 Installation über Homebrew
Wenn Sie macOS verwenden und bereits den Homebrew Paketmanager installiert haben, ist die Installation von Atlas so einfach wie das Ausführen des Befehls:
brew install ariga/tap/atlas
Dadurch wird die neueste Version von Atlas aus dem Repository von Homebrew abgerufen und installiert.
2.3 Docker-Installation
Die Installation und Ausführung von Atlas über Docker ist eine schnelle und bequeme Methode, insbesondere für temporäres Testen oder für Benutzer, die keine zusätzliche Software auf ihrem Hostsystem installieren möchten.
Zuerst müssen Sie das Atlas Docker-Image herunterladen:
docker pull arigaio/atlas
Anschließend können Sie einen Hilfebefehl ausführen, um eine erfolgreiche Installation zu bestätigen:
docker run --rm arigaio/atlas --help
Wenn der Container auf das Hostnetzwerk oder lokale Verzeichnisse zugreifen muss, verwenden Sie das --net=host
-Flag und mounten Sie die erforderlichen Verzeichnisse:
docker run --rm --net=host \
-v $(pwd)/migrations:/migrations \
arigaio/atlas migrate apply \
--url "mysql://root:pass@:3306/test"
2.4 Installation unter Windows
Laden Sie die Binärdatei herunter, https://release.ariga.io/atlas/atlas-windows-amd64-latest.exe, und fügen Sie den Installationspfad der Systemumgebungsvariable PATH hinzu.
3. Exportieren der vorhandenen Datenbanktabellenstruktur mit Atlas
Atlas bietet das Befehlskennwort atlas schema inspect
, das verwendet werden kann, um die Struktur einer vorhandenen Datenbank zu exportieren. Dieser Befehl unterstützt das Lesen von Datenbankbeschreibungen von der Datenbank-URL und gibt sie in drei verschiedenen Formaten aus: dem Standard-Atlas-HCL-Format, dem SQL-Format und dem JSON-Format. In dieser Anleitung zeigen wir, wie die Atlas-HCL- und SQL-Formate verwendet werden, da das JSON-Format typischerweise für die Verarbeitung von Ausgaben mit jq
verwendet wird.
Um eine lokal laufende MySQL-Instanz zu inspizieren und die Ausgabe in eine Datei mit dem Namen schema.hcl
zu schreiben, verwenden Sie den folgenden Befehl:
atlas schema inspect -u "mysql://root:pass@localhost:3306/example" > schema.hcl
Öffnen Sie die Datei schema.hcl
, um die Atlas-Tabellenstrukturdefinition anzuzeigen, die die Datenbank beschreibt (HCL ist ein datenbankunabhängiges Tabellenstrukturkonfigurationsformat, das von Atlas definiert ist). Diese Datei wird beispielsweise den folgenden Inhalt enthalten:
table "users" {
schema = schema.example
column "id" {
null = false
type = int
}
column "name" {
null = true
type = varchar(100)
}
primary_key {
columns = [column.id]
}
}
Dieser Codeblock stellt eine Tabellenstruktur mit den Spalten id
und name
dar. Das Feld schema
verweist auf die anderswo in diesem Dokument definierte Modelldefinition example
. Darüber hinaus gibt der Unterblock primary_key
die Spalte id
als Primärschlüssel für die Tabelle an. Atlas strebt danach, die Syntax der verwendeten Datenbank zu imitieren. In diesem Beispiel hat die Spalte id
den Typ int
, während die Spalte name
den Typ varchar(100)
hat.
Ähnlich können Sie zur Exportierung einer SQL-Modelldefinition der Datenbank den folgenden Befehl verwenden:
atlas schema inspect -u "mysql://root:pass@localhost:3306/example" --format '{{ sql . }}' > schema.sql
Öffnen Sie die Datei schema.sql
, um die SQL-Beschreibung der Datenbank anzuzeigen, die typischerweise einige CREATE TABLE-Anweisungen enthält.
Diese Methode erleichtert das Verständnis der Details der bestehenden Datenbanktabellenstruktur und liefert eine genaue Referenz für nachfolgende versionierte Migrationen.
4.1 Deklarativer Workflow
Der deklarative Workflow von Atlas ermöglicht es Benutzern, den gewünschten endgültigen Zustand der Datenbank deklarativ zu definieren. Benutzer müssen nur beschreiben, wie der endgültige Zustand des Datenbankschemas sein soll, und das Atlas-Tool generiert und führt automatisch Migrationspläne aus, um das Datenbankschema sicher vom aktuellen Zustand zu diesem erwarteten Zustand zu überführen.
So verwenden Sie den deklarativen Workflow, um den gewünschten Datenbankzustand zu definieren und zu erreichen:
4.1.1 Definition der Zieltabellenstruktur
Zunächst müssen Sie eine Datei erstellen, die die erwartete Datenbankstruktur definiert, die im HCL-, SQL- oder ORM (Object-Relational Mapping)-Format vorliegen kann.
Nehmen wir zum Beispiel das HCL-Format und definieren eine neue Tabelle 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]
}
}
Tipp: Das Syntaxformat von HCL wird in einem späteren Abschnitt behandelt.
4.1.2 Migration mit dem Atlas-Tool durchführen
Nachdem die Definition der Datenbanktabellenstruktur abgeschlossen ist, können Sie das Befehlskennwort schema apply
von Atlas verwenden, um die Migration durchzuführen.
atlas schema apply \
-u "mysql://root:pass@localhost:3306/example" \
--to file://schema.hcl
Nach Ausführung des obigen Befehls vergleicht Atlas das vorhandene Datenbankschema mit dem in der Datei definierten Schema, generiert einen Migrationsplan und fragt den Benutzer nach Bestätigung zur Ausführung. Sobald der Benutzer den Ausführungsplan bestätigt, führt Atlas die Migration auf der Datenbank durch und aktualisiert sie auf den gewünschten Zustand.
4.2 Versionierter Workflow
Der versionierte Workflow ist ein weiterer von Atlas unterstützter Anwendungsmodus, der manchmal als "Änderungsbasierte Migration" bezeichnet wird. Er eignet sich für Szenarien, in denen Datenbankschemaänderungen versioniert und im Code-Review-Prozess überprüft werden müssen.
Die Schritte des versionierten Workflows umfassen:
4.2.1 Unterschiede berechnen
Vor dem Start der Migration ist es notwendig, die aktuelle Datenbankstruktur mit dem gewünschten Zustand zu vergleichen und die Unterschiede zwischen den beiden festzustellen. Dies kann durch Ausführen des Befehls atlas migrate diff
erreicht werden.
atlas migrate diff create_blog_posts \
--dir "file://migrations" \
--to "file://schema.hcl" \
--dev-url "docker://mysql/8/example"
Das --dir
gibt die URL des Migrationsordners an und ist standardmäßig auf file://migrations
eingestellt. Das --to
gibt die URL des gewünschten Zustands an (z.B. Ihre Entwicklungsdatenbankumgebung), und --dev-url
bietet eine URL für eine Entwicklungsdatenbank zur Berechnung der Unterschiede (beachten Sie, dass diese --dev-url
eine leere Datenbank angeben muss, die Atlas zur Berechnung der Unterschiede verwendet).
Tipp: Wenn Sie SQL-Dateien generieren möchten, finden Sie im vorherigen Abschnitt Informationen zur Einstellung des Formats mithilfe des
--format
-Parameters.
4.2.2 Migrationsänderungen anwenden
Nach Abschluss der Unterschiedsberechnung generiert Atlas zwei Migrationsdateien, die im Ordner migrations
gespeichert sind. Wenn z.B. das ausgewählte Format SQL ist, enthalten die durch den diff
-Befehl generierten Dateien, wie die folgende SQL-Datei, Migrationsbefehle zur Erstellung einer neuen Tabelle:
-- Tabelle "blog_posts" erstellen
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`)
);
Sobald die Migrationsdateien generiert sind, können Sie Versionskontrollwerkzeuge (z.B. Git) verwenden, um diese Änderungen zu verwalten. Dieser Ansatz ermöglicht es, zahlreiche Änderungen an der Datenbanktabellenstruktur in der Entwicklungsumgebung vorzunehmen und bei Veröffentlichung die Entwicklungsumgebung mit der UAT-Umgebung mithilfe von Atlas-Befehlen zu vergleichen, um Migrationsdateien für die Datenbanktabellenstruktur zu generieren. Diese Migrationsdateien können dann auf die UAT- und Produktionsumgebungen angewendet werden, um die Datenbank zu aktualisieren.
Diese beiden Workflows, Deklarativ und Versioniert, bieten Flexibilität für verschiedene Entwicklungs- und Bereitstellungsmodi und ermöglichen es Teams, die Methode zu wählen, die am besten zu den Projektanforderungen für das Management von Datenbankschemänderungen passt.
5. Beschreibung des HCL-Formats
5.1 Einführung
HCL ist eine deklarative Sprache, die zur Beschreibung von Datenbanktabellenstrukturdefinitionen verwendet wird. Atlas verwendet das HCL-Format, um Datenbankschemata zu schreiben, und bietet eine umfangreiche Struktur zur Beschreibung verschiedener Aspekte der Datenbank. Der Vorteil von HCL liegt in seiner Lesbarkeit, der einfachen Wartung und der Unterstützung von Funktionen wie Variableneinspritzung und zusätzlichen Annotationen.
Tipp: Wenn Ihr Projekt sich an mehrere Datenbanken anpassen muss, kann die Beschreibung von Tabellenstrukturen in einer datenbankagnostischen Weise mithilfe von HCL sehr bequem sein.
5.2 schema
-Objekt
Das schema
-Objekt wird verwendet, um ein Datenbankschema zu beschreiben. In MySQL und SQLite repräsentiert es die DATENBANK
, während es in PostgreSQL das SCHEMA
repräsentiert. Eine HCL-Datei kann ein oder mehrere schema
-Objekte enthalten.
schema "public" {
comment = "Ein Schemakommentar"
}
schema "private" {}
5.3 table
-Objekt
Das table
-Objekt wird verwendet, um eine Tabelle in einer SQL-Datenbank zu beschreiben, einschließlich Spalten, Indizes, Einschränkungen und verschiedenen zusätzlichen Eigenschaften, die von verschiedenen Datenbanktreibern unterstützt werden.
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 column
-Objekt
Die column
ist eine Unterressource von table
, die verwendet wird, um die Spalten in der Tabelle zu definieren.
column "name" {
type = text
null = false
}
column "age" {
type = integer
default = 42
}
column "active" {
type = tinyint(1)
default = true
}
5.5 Objekt primary_key
Das Objekt primary_key
ist eine Unterressource von table
, die den Primärschlüssel der Tabelle definiert.
primary_key {
columns = [spalte.id]
}
5.6 Objekt foreign_key
Das Objekt foreign_key
ist eine Unterressource von table
, die Spalten definiert, die auf Spalten in anderen Tabellen verweisen.
table "orders" {
schema = schema.market
// ...
column "owner_id" {
type = integer
}
foreign_key "owner_id" {
columns = [spalte.owner_id]
ref_columns = [table.users.column.id]
on_update = NO_ACTION
on_delete = NO_ACTION
}
}
5.7 Objekt index
Das Objekt index
repräsentiert einen Index auf der Tabelle.
index "idx_name" {
columns = [
spalte.name
]
unique = true
}