Migrationskonzepte#
RESTAlchemy verwendet explizite Migrationsdateien, um das Datenbankschema weiterzuentwickeln.
Migrationen liegen in einem Verzeichnis (z.B. examples/migrations/) und werden über CLI-Tools wie ra-new-migration, ra-apply-migration, ra-rollback-migration und ra-rename-migrations ausgeführt.
Migrationsdateien#
Jede Migration ist eine Python-Datei mit einem migration_step Objekt:
from restalchemy.storage.sql import migrations
class MigrationStep(migrations.AbstractMigrationStep):
def __init__(self):
self._depends = ["<prev-migration-file>.py"]
@property
def migration_id(self):
return "<uuid>"
@property
def is_manual(self):
return False
def upgrade(self, session):
pass
def downgrade(self, session):
pass
migration_step = MigrationStep()
Die Vorlage für neue Migrationen liegt in:
restalchemy/storage/sql/migration_templ.tmpl
und wird von ra-new-migration verwendet.
Identifikatoren und Abhängigkeiten#
Jede Migration besitzt:
- Eine UUID (
migration_id). - Eine Abhängigkeitsliste (
self._depends) mit Dateinamen anderer Migrationen. - Ein Flag
is_manual.
Abhängigkeiten bilden einen gerichteten azyklischen Graphen. Beim Anwenden einer Migration werden zuerst alle Abhängigkeiten angewendet.
Spezielle Konstanten:
HEAD— steht für die „letzte automatische Migration“.MANUAL— Kennzeichnung für manuelle Migrationen im Dateinamen.
Der MigrationEngine nutzt diese Informationen, um:
- Teilnamen auf konkrete Dateinamen abzubilden.
- Die Head-Migration zu bestimmen.
- Sicherzustellen, dass automatische Migrationen nicht von manuellen abhängen.
Dateinamen und Nummerierung#
Neuer Namensstandard für Migrationen:
migration_number— Zahl mit führenden Nullen (0001,0002, ...).message-with-dashes— aus--message, Leerzeichen →-.hash— erste 6 Zeichen der UUID.
Für manuelle Migrationen:
Der alte Namensstandard wird weiterhin unterstützt; ra-rename-migrations kann alte Dateien auf das neue Schema umbenennen und Abhängigkeiten anpassen.
Wenn die Nachricht mit einer 4-stelligen Zahl beginnt, wird diese Zahl direkt als migration_number verwendet.
Statusverfolgung#
Angewendete Migrationen werden in der Tabelle ra_migrations verfolgt:
- Modell:
MigrationModel. - Spalten:
uuid— Primärschlüssel, Migration-UUID.applied— Bool, angewendet oder nicht.
MigrationEngine sorgt für das Vorhandensein der Tabelle und nutzt sie, um:
- Nicht angewendete Migrationen zu finden.
- Zu entscheiden, ob ein Rollback möglich ist.
Automatische vs. manuelle Migrationen#
- Automatische Migrationen (
is_manual == False): - Dürfen nur von anderen automatischen Migrationen abhängen.
- Werden bei der Bestimmung der Head-Migration berücksichtigt.
- Manuelle Migrationen (
is_manual == True): - Enthalten oft spezielle oder schwer rückgängig zu machende Änderungen.
- Werden bei der Head-Berechnung ausgelassen.
ra-new-migration prüft, dass automatische Migrationen keine manuellen in ihren Abhängigkeiten haben; andernfalls bricht der Befehl mit Fehler ab.
Typischer Workflow#
- DM-Modelle definieren und im Laufe der Zeit anpassen.
- Bei Schemaänderungen neue Migration per
ra-new-migrationerzeugen. upgrade()/downgrade()in der Migrationsdatei implementieren.- Migrationen mit
ra-apply-migrationanwenden. - Falls nötig, mit
ra-rollback-migrationzurückrollen. - Beim Umstieg auf das neue Namensschema
ra-rename-migrationsverwenden.