Migrations in Laravel richtig nutzen

In diesem Artikel möchte ich euch Migrations vorstellen. Was sind Migrations? Wie sehen sie aus und wie verwendet man sie richtig?

Was sind Migrations

Mit Migrations kann man für sein Projekt eine aktuelle Datenbankstruktur festhalten, die sich beliebig wiederherstellen lässt. Strukturänderungen an Datenbanktabellen werden in Klassen definiert. Klingt erstmal kompliziert, ist aber mit Laravel sehr einfach zu bewerkstelligen. Früher habe ich mir dazu immer SQL-Dumps der Struktur gesichert. Nachteil an dieser Methode ist, ich habe es öfter mal vergessen und Änderungen in der Struktur sind aufwendiger herzustellen. Zudem hatte ich keinen Zugriff auf die Zwischenschritte der Strukturänderungen die gemacht wurden.

Mit den Laravel Migrations geht man den umgekehrten Weg. Man erstellt erst die Struktur der Datenbank in Form von Migrations-Dateien und spielt diese dann über php artisan migrate ein. Somit hat man immer eine aktuelle Abbildung der Struktur.

Ganz wichtig hierbei: Man erstellt für jede Änderung eine neue Migrations-Datei. Darin befinden sich nur die Änderungen zum vorherigen Stand der Tabellenstruktur und nicht die gesamte Tabelle. Somit lassen sich Änderungen mit einem einfachen php aritsan migrate:rollback auch wieder rückgängig machen.

Praxisbeispiel

Ich möchte eine persons Tabelle erstellen und mit Basisfeldern bestücken.

Dazu lasse ich mir mit einem Aritsan Command die Migrations-Datei erstellen, und erhalte sofort eine Rückmeldung wie meine Migrations-Datei heißt:

# php artisan migrate:make create_persons_table
Created Migration: 2014_12_13_001212_create_persons_table

Schauen wir die Datei an, finden wir eine Klasse CreatePersonsTable die die Klasse Migrations erweitert. Das bedeutet uns stehen alle möglichen Methoden aus der Migrations Klasse zur verfügung. Ausserdem sehen wir zwei Methoden up() und down(). up() wird ausgeführt wenn die Migration eingespielt wird, down() wenn ein Rollback stattfindet.

In der Dokumentation über den Schema-Builder finden wir alle Methoden mit denen wir unsere Datenbankstruktur erstellen oder modifizieren können. Wir halten nun die gewünschte Struktur fest:

function up() {
  Schema::create('students', function(Blueprint $table) {
    $table->increments('id');
    $table->string('name');
    $table->string('firstname');
    $table->text('address')->nullable();
    $table->date('date_of_birth')->nullable();
    $table->timestamps();
  }
}

function down() {
  Schema::drop('students');
}

Mit php artisan migrate wird unsere Datei eingespielt und alle Änderungen vorgenommen.

Hinweis: Sollte das die erste Migration sein, muss die Datenbank vorbereitet werden. Das erledigt man ganz einfach mit php artisan migrate:install. Jetzt enthält unsere Datenbank eine Tabelle migrations die quasi den Verlauf unserer Datenbank fest hält. Uns braucht die Tabelle nicht zu interessieren - Laravel kümmert sich darum.

Datenbanktabelle verändern

Die Basisfelder unserer persons Tabelle sind schon ganz gut. Im Verlauf des Projektes kommen wir nun auf die Idee, dass jede Person auch eine Biografie haben kann. Das bedeutet wir müssen unsere Struktur dahingehend anpassen.

Im konkreten Beispiel erstellen wir uns eine neue Migrations-Datei:

# php artisan migrate:make add_bio_to_persons_table
Created Migration: 2014_12_13_004224_add_bio_to_persons_table

Ich versuche immer schon im Dateinamen zu umreißen, welche Änderungen ich vornehme. Dass erleichtert mir die Suche, falls ich eine Änderung wiederfinden und modifizieren möchte. Und ganz wichtig: verwendet niemals die gleiche Beschriftung mehrfach. Erstellt Ihr nämlich nochmal die Migration mit derselben Bezeichnung wie beim ersten mal, ist zwar der Dateiname unterschiedlich (da sich der Zeitstempel ändert). Jedoch wird die Klasse nach der Bezeichnung in CamelCase benannt. Und zweimal denselben Klassennamen verwenden gibt eine PHP Exception aus.

Unsere Methoden up() und down() sehen wie folgt aus:

function up() {
  Schema::table('students', function(Blueprint $table) {
    $table->text('bio')->nullable();
  });
}

function down() {
  Schema::table('students', function(Blueprint $table) {
    $table->dropColumn('bio');
  });
}

Wichtig ist erstmal dass einem klar wird dass wir hier keine Tabelle erstellen, sondern mit einer vorhandenen Tabelle arbeiten. Daher auch Schema::table() und nicht wie im ersten Fall Schema::create(). Für ein Rollback verwerfen wir hier wieder nur die Spalte ($table->dropColumn()), und nicht wie oben, die ganze Tabelle (Schema::drop()).

Um unsere Änderung einzuspielen führen wir wieder ein php artisan migrate aus. Unsere Tabelle ist nun wieder aktuell.

Artisan Befehle

Wie gewöhnlich können wir uns im Terminal mit php artisan eine Auflistung aller Befehle anzeigen lassen.

Die wichtigsten sind nochmal hier zusammengefasst:

Fazit

Migrations sind eine einfache Möglichkeit seine Datenbankstruktur zu verwalten. Entwicklet man im Team, ist das sowieso unabdingbar. Jeder im Team muss eine aktuelle Datenbankstruktur besitzen um vernünftig arbeiten zu können. Mit Migrations kann sich jeder mit nur wenigen Kommandozeilen Befehlen seine Datenbankstruktur aktualisieren.

Hilfreich ist es auch, wenn man sich in einer neuen Entwicklungsumgebung einrichten möchte. Anstatt des SQL-Dumps, spiele ich hier die Migrations ein. Das ist wesentlich einfacher, übersichtlicher und flexibler bei Rollbacks und Änderungen.

Letzte Tips