Migrations

1.  Grundlegendes zu Migrations

Unter Migrations versteht man den Umzug von Daten in eine andere Umgebung. Bei den Migrationen gibt es unterschiedliche Domänen. So ist eine Domäne "studip" vorhanden in der die Versionsprotokollierung von Stud.IP zu finden ist. Analog gibt es auch für jedes Plugin eine Migrationsdomäne.

1.1  Aufbau von Migrations-Skripten:

Migrationsskripte bestehen in der Grundlage aus mindestens zwei Funktionen, zu denen eine dritte, optionale, hinzu kommt.

Unbedingt erforderlich sind die Funktionen up() und down(). In up() werden die Änderungen durchgeführt und entsprechend in down() die Änderungen der up() Methode wieder rückgängig gemacht. (->siehe Irreversible Migrationen)

Die Funktion description() liefert eine Beschreibung der durchzuführenden Migration.

In Kernmigrationen sollten keine APIs aus dem Kern verwendet werden (beispielsweise Config), da nicht gewährleistet ist, dass diese sich nicht ändern werden. Es sollten immer die entsprechenden Datenbankeinträge manuell vorgenommen werden. Für Plugins gilt dies nicht. Pluginmigrationen sollten immer die entsprechende API verwenden. Falls Pluginmigrationen APIs des Plugins verwenden, kann es allerdings analoge Probleme zu Kern-APIs in Kernmigrationen geben - also hier auch vorsichtig sein.

1.2  Basisklasse der Migrationsskripte

Grundsätzlich müssen alle Migrationsklassen die Klasse Migration erweitern.

1.3  Namensgebung

Die Migrationsdateien müssen fortlaufend nummeriert werden, beginnend bei 1 und haben immer ganzzahlige Versionsnummern (1, 2, 3, usw.). Es sollten keine Zahlensprünge größer als 1 in der Nummerierung vorhanden sein, führende Nullen dürfen verwendet werden (z.B. 001 statt 1). Zusätzlich zur Version kann es einen Branch geben, der der Versionsnummer vorangestellt wird, z.B. "5.1" - die komplette Bezeichnung ist dann Branch.Version_klassenname.php. Beispiele dafür wären 3.1 oder 289.5.2. Der Branch ist optional und hat nur den Sinn, nachträglich Migrationen "zwischen" vorherige Migrationen schieben zu können.

Insgesamt kann man sich die Kombination aus Branch und Versionsnummer wie eine Software-Versionsbezeichnung vorstellen.

Für das Stud.IP-Release wird ab der Version 5.1 folgendes Numerierungsschema verwendet:

  • Alte Migrationen (vor 5.1) haben Nummern auf dem 1.x Branch, also "1.1" usw.
  • Migrationen ab 5.1 bekommen Nummern gemäß der Version, ab der sie hinzugefügt wurden - z.B. "5.1.1", "5.2.3" usw.

Jede Domäne (d.h. jedes Plugin) hat eine eigenständige Zählung der Migrationsschritte und Plugins müssen sich auch nicht an das o.g. Schema halten, d.h. sie können weiterhin einfach ihre Migrationen fortlauftend ab 1 numerieren. Plugin-Migrationen können aber natürlich auch in Branches aufgeteilt werden.

1.4  Reversible und Irreversible Migrationen

Bei reversiblen Migrationen besteht die Möglichkeit über die up() und down() Methoden immer in eine andere Version zu springen. Bei irreversiblem Migrationen verändert die up() Funktion die vorhandenen Daten derart, dass ein Aufruf der down() Funktion diese nicht wieder herstellen kann. In solchen Fällen sollte unbedingt eine Fehlerbehandlung in der down() Funktion des Migrationsschrittes erfolgen.

1.5  Ausführung von Migrationen

Für die Ausführung von Migrationen gibt es zwei Möglichkeiten:

Ausführung über die Kommandozeile

In dem Ordner /cli/ befindet sich ein Skript, das die Migrationen über die Kommandozeile ausführt. Hier ist auch Migration von Plugins möglich, die vom Webinterface nicht direkt unterstützt werden.

Erforderliche Parameter

  • d: Domäne (default studip)
  • m: Dateipfad zum Ordner mit den Migrationsdateien
  • l: Nur auflisten was getan werden soll nicht migrieren
  • t: Zielmigration (0 für komplettes Reset, andernfalls Zielversionsnummer)
  • b: Branch, auf dem die Migration passieren soll (optional)
  • v: verbose (empfohlen)

Beispiel: Stud.IP Migrationen von 6 rückgängig machen auf 5: ./migrate.php -d studip -m ../db/migrations/ -t 5 -v

Beispiel: Ausgabe mit l Parameter: @@ ./migrate.php -d studip -l ../db/migrations/ -t 18

  3 Step87ExternConfigurations Extends table extern_config and converts configurations for the external pages from 
    INI-style files to serialised arrays stored in the database.
  4 Step116ParticipantView creates table necessary for StEP116
  5 Step25RaumzeitMigrations modify db schema for StEP00025; see logfile in $TMP_PATH
  6 Step25RaumzeitDbConversion convert dates for StEP00025; see logfile in $TMP_PATH
  7 TableTokenClass      creates table for Token class
  8 Step117StudienModule modify db schema StEP00117 Studienmodulstrukturen; 
  9 StEP00111Admission   creates table admission groups
 10 ImageProxy           creates table image_proxy_cache and config entry EXTERNAL_IMAGE_EMBEDDING
 11 LockRules            creates table for lock rules
 12 Step120Userpic       modify existing user pictures according to Step00120
 13 RemoveFieldsFromExtermine removes expire|repeat|color|priority from table ex_termine
 14 StEP00123Admission2  modifies table seminare, adds field `admission_enable_quota`
 15 Step00129EmailRestriction Adds the new Value EMAIL_DOMAIN_RESTRICTION to table config.
 16 Step00126EmbeddingFlashMovies Adds the new values EXTERNAL_
    FLASH_MOVIE_EMBEDDING and DOCUMENTS_EMBEDD_FLASH_MOVIES to table config.
 17 DbOptimierungKontingentierung adds keys in admission_seminar_studiengang, admission_seminar_user and seminar_user
 18 Step00139UploadFileReorg reorganize uploaded files into sub-folders@@

Ausführung über die Web-Oberfläche

Das web_migrate Skript unter /public/web_migrate.php hat die gleichen Funktionen wie die oben beschriebene Kommandozeiolenversion, kann aber interaktiv verwendet werden (siehe Screenshot).

2.  Beispielplugin mit Migration

Elmar hat einfach mal ein kleines Beispiel fertiggemacht: das "DummyPlugin" (ein Plugin, da die Verwendung für die Plugin-Schnittstelle vorrangig von Interesse ist). Die Katalogstruktur des Plugins sieht folgendermaßen aus:

  DummyPlugin.class.php 
  plugin.manifest 
  sql/ 
    sql/dummy_install.sql 
    sql/dummy_uninstall.sql 
  migrations/ 
    migrations/1_test.php 
    migrations/2_foo.php 

Die SQL-Dateien unter sql definieren wie gehabt das "Grundlayout" für das Plugin und sind entsprechend als "dbscheme" (bzw. "uninstalldbscheme") im Manifest eingetragen, soweit also nichts neues. Neu hingekommen ist der Katalog migrations, der die einzelnen Deltas enthält, die von Plugin-Version zu Plugin-Version nachgezogen werden müssen (diese werden also nicht mehr in sql/dummy_install.sql abgebildet). Jeder Versionsschritt des Plugins kann beliebig viele solche Deltas ( = Migrations) besitzen. Alle Migrations sind aufsteigend numeriert, die Dateinamen folgen dabei der Konvention nummer_klassenname.php.

Jede Migration ist eine PHP-Klasse mit den Operationen up() und down(), die die jeweiligen Änderungen durchführen bzw. wieder zurücknehmen können. Als Beispiel hier der Inhalt von migrations/1_test.php:

  <? 
  class Test extends Migration { 
      function up () {
          $db = DBManager::get();
          $db->exec("INSERT INTO dummy VALUES (42, 'axel')"); 
      } 

      function down () {
          $db = DBManager::get();
          $db->exec("DELETE FROM dummy WHERE id = 42"); 
      } 
  } 
  ?> 

Anstatt Werte in eine Tabelle einzutragen könnte man natürlich ebenfalls neue Tabellen anlegen, Felder hinzufügen oder entfernen, Daten umwandeln oder in eine andere Tabelle kopieren, Dateien oder Kataloge anlegen, Rechte setzen usw. (es muß nichts mit der DB zu tun haben). Der Zugriff auf die Datenbank erfolgt dabei wie üblich über die DBManager-Klasse. Alles weitere passiert (bei Plugins) automatisch, d.h. beim Update eines Plugins werden - ausgehend vom aktuellen Versionsstand - alle notwendigen Änderungen (d.h. Migrations) durchgeführt bzw. bei einem Downgrade eines Plugins entsprechend wieder zurückgenommen.

PS: Wenn man möchte, kann man natürlich auch "dbscheme" und "uninstalldbscheme" im Manifest weglassen und das Anlegen der kompletten DB-Struktur für das Plugin über Migrations erledigen.

Für ein Beispiel für die Migration eines Plugins gibt es hier ein kleines Zip file:

Attach:dummy_plugin-v0.3.zip

Letzte Änderung am September 01, 2021, at 12:03 PM von eludwig.